Asterisk - The Open Source Telephony Project GIT-master-85241bd
res_speech_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 * Kevin Harwell <kharwell@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/*! \file
20 *
21 * \brief Asterisk External Application Speech Engine
22 *
23 */
24
25/*** MODULEINFO
26 <support_level>core</support_level>
27 ***/
28
29#include "asterisk.h"
30
31#include "asterisk/astobj2.h"
32#include "asterisk/config.h"
33#include "asterisk/format.h"
34#include "asterisk/format_cap.h"
35#include "asterisk/json.h"
36#include "asterisk/module.h"
37#include "asterisk/speech.h"
38#include "asterisk/sorcery.h"
39
40#include "asterisk/res_aeap.h"
42
43#define SPEECH_AEAP_VERSION "0.1.0"
44#define SPEECH_PROTOCOL "speech_to_text"
45
46#define CONNECTION_TIMEOUT 2000
47
48#define log_error(obj, fmt, ...) \
49 ast_log(LOG_ERROR, "AEAP speech (%p): " fmt "\n", obj, ##__VA_ARGS__)
50
51static struct ast_json *custom_fields_to_params(const struct ast_variable *variables)
52{
53 const struct ast_variable *i;
54 struct ast_json *obj;
55
56 if (!variables) {
57 return NULL;
58 }
59
61 if (!obj) {
62 return NULL;
63 }
64
65 for (i = variables; i; i = i->next) {
66 if (i->name[0] == '@' && i->name[1]) {
68 }
69 }
70
71 return obj;
72}
73
74/*!
75 * \internal
76 * \brief Create, and send a request to the external application
77 *
78 * Create, then sends a request to an Asterisk external application, and then blocks
79 * until a response is received or a time out occurs. Since this method waits until
80 * receiving a response the returned result is guaranteed to be pass/fail based upon
81 * a response handler's result.
82 *
83 * \param aeap Pointer to an Asterisk external application object
84 * \param name The name of the request to send
85 * \param json The core json request data
86 * \param data Optional user data to associate with request/response
87 *
88 * \returns 0 on success, -1 on error
89 */
90static int speech_aeap_send_request(struct ast_aeap *aeap, const char *name,
91 struct ast_json *json, void *data)
92{
93 /*
94 * Wait for a response. Also since we're blocking,
95 * data is expected to be on the stack so no cleanup required.
96 */
97 struct ast_aeap_tsx_params tsx_params = {
98 .timeout = 1000,
99 .wait = 1,
100 .obj = data,
101 };
102
103 /* "steals" the json ref */
106 if (!tsx_params.msg) {
107 return -1;
108 }
109
110 /* Send "steals" the json msg ref */
111 return ast_aeap_send_msg_tsx(aeap, &tsx_params);
112}
113
114/*!
115 * \internal
116 * \brief Create, and send a "get" request to an external application
117 *
118 * Basic structure of the JSON message to send:
119 *
120 \verbatim
121 { param: [<param>, ...] }
122 \endverbatim
123 *
124 * \param speech The speech engine
125 * \param param The name of the parameter to retrieve
126 * \param data User data passed to the response handler
127 *
128 * \returns 0 on success, -1 on error
129 */
130static int speech_aeap_get(struct ast_speech *speech, const char *param, void *data)
131{
132 if (!param) {
133 return -1;
134 }
135
136 /* send_request handles json ref */
137 return speech_aeap_send_request(speech->data,
138 "get", ast_json_pack("{s:[s]}", "params", param), data);
139}
140
142 const char *name;
143 const char *value;
144};
145
146/*!
147 * \internal
148 * \brief Create, and send a "set" request to an external application
149 *
150 * Basic structure of the JSON message to send:
151 *
152 \verbatim
153 { params: { <name> : <value> } }
154 \endverbatim
155 *
156 * \param speech The speech engine
157 * \param name The name of the parameter to set
158 * \param value The value of the parameter to set
159 *
160 * \returns 0 on success, -1 on error
161 */
162static int speech_aeap_set(struct ast_speech *speech, const char *name, const char *value)
163{
164 if (!name) {
165 return -1;
166 }
167
168 /* send_request handles json ref */
169 return speech_aeap_send_request(speech->data,
170 "set", ast_json_pack("{s:{s:s}}", "params", name, value), NULL);
171}
172
173static int handle_response_set(struct ast_aeap *aeap, struct ast_aeap_message *message, void *data)
174{
175 return 0;
176}
177
179 const char *param;
180 size_t len;
181 char *buf;
182};
183
184static int handle_setting(struct ast_aeap *aeap, struct ast_json_iter *iter,
185 struct speech_setting *setting)
186{
187 const char *value;
188
189 if (strcmp(ast_json_object_iter_key(iter), setting->param)) {
190 log_error(aeap, "Unable to 'get' speech setting for '%s'", setting->param);
191 return -1;
192 }
193
195 if (!value) {
196 log_error(aeap, "No value for speech setting '%s'", setting->param);
197 return -1;
198 }
199
200 ast_copy_string(setting->buf, value, setting->len);
201 return 0;
202}
203
204static int handle_results(struct ast_aeap *aeap, struct ast_json_iter *iter,
205 struct ast_speech_result **speech_results)
206{
207 struct ast_speech_result *result = NULL;
208 struct ast_json *json_results;
209 struct ast_json *json_result;
210 size_t i;
211
212 json_results = ast_json_object_iter_value(iter);
213 if (!json_results || !speech_results) {
214 log_error(aeap, "Unable to 'get' speech results");
215 return -1;
216 }
217
218 for (i = 0; i < ast_json_array_size(json_results); ++i) {
219 if (!(result = ast_calloc(1, sizeof(*result)))) {
220 continue;
221 }
222
223 json_result = ast_json_array_get(json_results, i);
224
225 result->text = ast_strdup(ast_json_object_string_get(json_result, "text"));
226 result->score = ast_json_object_integer_get(json_result, "score");
227 result->grammar = ast_strdup(ast_json_object_string_get(json_result, "grammar"));
228 result->nbest_num = ast_json_object_integer_get(json_result, "best");
229 if (*speech_results) {
230 AST_LIST_NEXT(result, list) = *speech_results;
231 *speech_results = result;
232 } else {
233 *speech_results = result;
234 }
235 }
236
237 return 0;
238}
239
240/*!
241 * \internal
242 * \brief Handle a "get" response from an external application
243 *
244 * Basic structure of the expected JSON message to received:
245 *
246 \verbatim
247 {
248 response: "get"
249 "params" : { <name>: <value> | [ <results> ] }
250 }
251 \endverbatim
252 *
253 * \param aeap Pointer to an Asterisk external application object
254 * \param message The received message
255 * \param data User data passed to the response handler
256 *
257 * \returns 0 on success, -1 on error
258 */
259static int handle_response_get(struct ast_aeap *aeap, struct ast_aeap_message *message, void *data)
260{
261 struct ast_json_iter *iter;
262
264 if (!iter) {
265 log_error(aeap, "no 'get' parameters returned");
266 return -1;
267 }
268
269 if (!strcmp(ast_json_object_iter_key(iter), "results")) {
270 return handle_results(aeap, iter, data);
271 }
272
273 return handle_setting(aeap, iter, data);
274}
275
276static int handle_response_setup(struct ast_aeap *aeap, struct ast_aeap_message *message, void *data)
277{
278 struct ast_format *format = data;
279 struct ast_json *json = ast_aeap_message_data(message);
280 const char *codec_name;
281
282 if (!format) {
283 log_error(aeap, "no 'format' set");
284 return -1;
285 }
286
287 if (!json) {
288 log_error(aeap, "no 'setup' object returned");
289 return -1;
290 }
291
292 json = ast_json_object_get(json, "codecs");
293 if (!json || ast_json_array_size(json) == 0) {
294 log_error(aeap, "no 'setup' codecs available");
295 return -1;
296 }
297
298 codec_name = ast_json_object_string_get(ast_json_array_get(json, 0), "name");
299 if (!codec_name || strcmp(codec_name, ast_format_get_codec_name(format))) {
300 log_error(aeap, "setup codec '%s' unsupported", ast_format_get_codec_name(format));
301 return -1;
302 }
303
304 return 0;
305}
306
308 { "setup", handle_response_setup },
309 { "get", handle_response_get },
310 { "set", handle_response_set },
311};
312
313static int handle_request_set(struct ast_aeap *aeap, struct ast_aeap_message *message, void *data)
314{
315 struct ast_json_iter *iter;
316 const char *error_msg = NULL;
317
319 if (!iter) {
320 error_msg = "no parameter(s) requested";
321 } else if (!strcmp(ast_json_object_iter_key(iter), "results")) {
322 struct ast_speech *speech = ast_aeap_user_data_object_by_id(aeap, "speech");
323
324 if (!speech) {
325 error_msg = "no associated speech object";
326 } else if (handle_results(aeap, iter, &speech->results)) {
327 error_msg = "unable to handle results";
328 } else {
330 }
331 } else {
332 error_msg = "can only set 'results'";
333 }
334
335 if (error_msg) {
336 log_error(aeap, "set - %s", error_msg);
339 } else {
342 }
343
345
346 return 0;
347}
348
350 { "set", handle_request_set },
351};
352
353/*!
354 * \internal
355 * \brief Handle an error from an external application by setting state to done
356 *
357 * \param aeap Pointer to an Asterisk external application object
358 */
359static void ast_aeap_speech_on_error(struct ast_aeap *aeap)
360{
361 struct ast_speech *speech = ast_aeap_user_data_object_by_id(aeap, "speech");
362 if (!speech) {
363 ast_log(LOG_ERROR, "aeap generated error with no associated speech object");
364 return;
365 }
366
368}
369
372 .response_handlers_size = ARRAY_LEN(response_handlers),
373 .request_handlers = request_handlers,
374 .request_handlers_size = ARRAY_LEN(request_handlers),
375 .on_error = ast_aeap_speech_on_error,
376};
377
378/*!
379 * \internal
380 * \brief Create, and connect to an external application and send initial setup
381 *
382 * Basic structure of the JSON message to send:
383 *
384 \verbatim
385 {
386 "request": "setup"
387 "codecs": [
388 {
389 "name": <name>,
390 "attributes": { <name>: <value>, ..., }
391 },
392 ...,
393 ],
394 "params": { <name>: <value>, ..., }
395 }
396 \endverbatim
397 *
398 * \param speech The speech engine
399 * \param format The format codec to use
400 *
401 * \returns 0 on success, -1 on error
402 */
403static int speech_aeap_engine_create(struct ast_speech *speech, struct ast_format *format)
404{
405 struct ast_aeap *aeap;
406 struct ast_variable *vars;
407 struct ast_json *json;
408
411 if (!aeap) {
412 return -1;
413 }
414
415 speech->data = aeap;
416
417 /* Don't allow unloading of this module while an external application is in use */
419
420 vars = ast_aeap_custom_fields_get(speech->engine->name);
421
422 /* While the protocol allows sending of codec attributes, for now don't */
423 json = ast_json_pack("{s:s,s:[{s:s}],s:o*}", "version", SPEECH_AEAP_VERSION, "codecs",
424 "name", ast_format_get_codec_name(format), "params", custom_fields_to_params(vars));
425
427
428 if (ast_aeap_user_data_register(aeap, "speech", speech, NULL)) {
430 return -1;
431 }
432
433 /* send_request handles json ref */
434 if (speech_aeap_send_request(speech->data, "setup", json, format)) {
436 return -1;
437 }
438
439 /*
440 * Add a reference to the engine here, so if it happens to get unregistered
441 * while executing it won't disappear.
442 */
443 ao2_ref(speech->engine, 1);
444
445 return 0;
446}
447
448static int speech_aeap_engine_destroy(struct ast_speech *speech)
449{
450 ao2_ref(speech->engine, -1);
451 ao2_cleanup(speech->data);
452
454
455 return 0;
456}
457
458static int speech_aeap_engine_write(struct ast_speech *speech, void *data, int len)
459{
460 return ast_aeap_send_binary(speech->data, data, len);
461}
462
463static int speech_aeap_engine_dtmf(struct ast_speech *speech, const char *dtmf)
464{
465 return speech_aeap_set(speech, "dtmf", dtmf);
466}
467
468static int speech_aeap_engine_start(struct ast_speech *speech)
469{
471
472 return 0;
473}
474
475static int speech_aeap_engine_change(struct ast_speech *speech, const char *name, const char *value)
476{
477 return speech_aeap_set(speech, name, value);
478}
479
480static int speech_aeap_engine_get_setting(struct ast_speech *speech, const char *name,
481 char *buf, size_t len)
482{
483 struct speech_setting setting = {
484 .param = name,
485 .len = len,
486 .buf = buf,
487 };
488
489 return speech_aeap_get(speech, name, &setting);
490}
491
493 enum ast_speech_results_type results_type)
494{
495 return speech_aeap_set(speech, "results_type",
497}
498
500{
501 struct ast_speech_result *results = NULL;
502
503 if (speech->results) {
504 return speech->results;
505 }
506
507 if (speech_aeap_get(speech, "results", &results)) {
508 return NULL;
509 }
510
511 return results;
512}
513
514static void speech_engine_destroy(void *obj)
515{
516 struct ast_speech_engine *engine = obj;
517
518 ao2_cleanup(engine->formats);
519 ast_free(engine->name);
520}
521
522static struct ast_speech_engine *speech_engine_alloc(const char *name)
523{
524 struct ast_speech_engine *engine;
525
526 engine = ao2_t_alloc_options(sizeof(*engine), speech_engine_destroy,
528 if (!engine) {
529 ast_log(LOG_ERROR, "AEAP speech: unable create engine '%s'\n", name);
530 return NULL;
531 }
532
533 engine->name = ast_strdup(name);
534 if (!engine->name) {
535 ao2_ref(engine, -1);
536 return NULL;
537 }
538
547 engine->get = speech_aeap_engine_get;
548
550
551 return engine;
552}
553
554static void speech_engine_alloc_and_register(const char *name, const struct ast_format_cap *formats)
555{
556 struct ast_speech_engine *engine;
557
558 engine = speech_engine_alloc(name);
559 if (!engine) {
560 return;
561 }
562
565 ast_log(LOG_WARNING, "AEAP speech: Unable to add engine '%s' formats\n", name);
566 ao2_ref(engine, -1);
567 return;
568 }
569
570 if (ast_speech_register(engine)) {
571 ast_log(LOG_WARNING, "AEAP speech: Unable to register engine '%s'\n", name);
572 ao2_ref(engine, -1);
573 }
574}
575
576#ifdef TEST_FRAMEWORK
577
578static void speech_engine_alloc_and_register2(const char *name, const char *codec_names)
579{
580 struct ast_speech_engine *engine;
581
582 engine = speech_engine_alloc(name);
583 if (!engine) {
584 return;
585 }
586
587 if (codec_names && ast_format_cap_update_by_allow_disallow(engine->formats, codec_names, 1)) {
588 ast_log(LOG_WARNING, "AEAP speech: Unable to add engine '%s' codecs\n", name);
589 ao2_ref(engine, -1);
590 return;
591 }
592
593 if (ast_speech_register(engine)) {
594 ast_log(LOG_WARNING, "AEAP speech: Unable to register engine '%s'\n", name);
595 ao2_ref(engine, -1);
596 }
597}
598
599#endif
600
601static int unload_engine(void *obj, void *arg, int flags)
602{
605 }
606
607 return 0;
608}
609
610static int load_engine(void *obj, void *arg, int flags)
611{
612 const char *id;
613 const struct ast_format_cap *formats;
614 const struct ast_speech_engine *engine;
615
617 return 0;
618 }
619
622 if (!formats) {
624 if (!formats) {
625 ast_log(LOG_ERROR, "AEAP speech: unable to allocate default engine format for '%s'\n", id);
626 return 0;
627 }
628 }
629
630 engine = ast_speech_find_engine(id);
631 if (!engine) {
633 return 0;
634 }
635
637 /* Same name, same formats then nothing changed */
638 return 0;
639 }
640
641 ao2_ref(ast_speech_unregister2(engine->name), -1);
643
644 return 0;
645}
646
647static int matches_engine(void *obj, void *arg, int flags)
648{
649 const struct ast_speech_engine *engine = arg;
650
651 return strcmp(ast_sorcery_object_get_id(obj), engine->name) ? 0 : CMP_MATCH;
652}
653
654static int should_unregister(const struct ast_speech_engine *engine, void *data)
655{
656 void *obj;
657
658 if (engine->create != speech_aeap_engine_create) {
659 /* Only want to potentially unregister AEAP speech engines */
660 return 0;
661 }
662
663#ifdef TEST_FRAMEWORK
664 if (!strcmp("_aeap_test_speech_", engine->name)) {
665 /* Don't remove the test engine */
666 return 0;
667 }
668#endif
669
670 obj = ao2_callback(data, 0, matches_engine, (void*)engine);
671
672 if (obj) {
673 ao2_ref(obj, -1);
674 return 0;
675 }
676
677 /* If no match in given container then unregister engine */
678 return 1;
679}
680
681static void speech_observer_loaded(const char *object_type)
682{
683 struct ao2_container *container;
684
685 if (strcmp(object_type, AEAP_CONFIG_CLIENT)) {
686 return;
687 }
688
690 if (!container) {
691 return;
692 }
693
694 /*
695 * An AEAP module reload has occurred. First
696 * remove all engines that no longer exist.
697 */
699
700 /* Now add or update engines */
702 ao2_ref(container, -1);
703}
704
705/*! \brief Observer for AEAP reloads */
708};
709
710static int unload_module(void)
711{
712 struct ao2_container *container;
713
714#ifdef TEST_FRAMEWORK
715 ao2_cleanup(ast_speech_unregister2("_aeap_test_speech_"));
716#endif
717
719
721 if (container) {
723 ao2_ref(container, -1);
724 }
725
726 return 0;
727}
728
729static int load_module(void)
730{
731 struct ao2_container *container;
732
734
736 if (container) {
738 ao2_ref(container, -1);
739 }
740
741 /*
742 * Add an observer since a named speech server must be created,
743 * registered, and eventually removed for all AEAP client
744 * configuration matching the "speech_to_text" protocol.
745 */
748 }
749
750#ifdef TEST_FRAMEWORK
751 speech_engine_alloc_and_register2("_aeap_test_speech_", "ulaw");
752#endif
753
755}
756
757AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "Asterisk External Application Speech Engine",
758 .support_level = AST_MODULE_SUPPORT_CORE,
759 .load = load_module,
760 .unload = unload_module,
761 .load_pri = AST_MODPRI_CHANNEL_DEPEND,
762 .requires = "res_speech,res_aeap",
enum queue_result id
Definition: app_queue.c:1638
Asterisk main include file. File version handling, generic pbx functions.
#define ast_free(a)
Definition: astmm.h:180
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:241
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:202
#define ast_log
Definition: astobj2.c:42
@ CMP_MATCH
Definition: astobj2.h:1027
@ AO2_ALLOC_OPT_LOCK_NOLOCK
Definition: astobj2.h:367
#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
#define ao2_cleanup(obj)
Definition: astobj2.h:1934
#define ao2_t_alloc_options(data_size, destructor_fn, options, debug_msg)
Allocate and initialize an object.
Definition: astobj2.h:402
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
void __ao2_cleanup(void *obj)
Definition: astobj2.c:677
static PGresult * result
Definition: cel_pgsql.c:84
@ AST_MEDIA_TYPE_AUDIO
Definition: codec.h:32
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
static struct formats formats
Media Format API.
const char * ast_format_get_codec_name(const struct ast_format *format)
Get the codec name associated with a format.
Definition: format.c:339
Format Capabilities API.
int ast_format_cap_update_by_allow_disallow(struct ast_format_cap *cap, const char *list, int allowing)
Parse an "allow" or "deny" list and modify a format capabilities structure accordingly.
Definition: format_cap.c:320
@ AST_FORMAT_CAP_FLAG_DEFAULT
Definition: format_cap.h:38
int ast_format_cap_append_from_cap(struct ast_format_cap *dst, const struct ast_format_cap *src, enum ast_media_type type)
Append the formats of provided type in src to dst.
Definition: format_cap.c:269
int ast_format_cap_identical(const struct ast_format_cap *cap1, const struct ast_format_cap *cap2)
Determine if two capabilities structures are identical.
Definition: format_cap.c:687
#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
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
Configuration File Parser.
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
Definition: extconf.c:1262
#define LOG_ERROR
#define LOG_WARNING
Asterisk JSON abstraction layer.
#define ast_json_object_string_get(object, key)
Get a string field from a JSON object.
Definition: json.h:600
struct ast_json * ast_json_object_iter_value(struct ast_json_iter *iter)
Get the value from an iterator.
Definition: json.c:455
struct ast_json * ast_json_string_create(const char *value)
Construct a JSON string from value.
Definition: json.c:278
struct ast_json * ast_json_object_create(void)
Create a new JSON object.
Definition: json.c:399
struct ast_json * ast_json_array_get(const struct ast_json *array, size_t index)
Get an element from an array.
Definition: json.c:370
struct ast_json * ast_json_pack(char const *format,...)
Helper for creating complex JSON values.
Definition: json.c:612
struct ast_json_iter * ast_json_object_iter(struct ast_json *object)
Get an iterator pointing to the first field in a JSON object.
Definition: json.c:439
int ast_json_object_set(struct ast_json *object, const char *key, struct ast_json *value)
Set a field in a JSON object.
Definition: json.c:414
#define ast_json_object_integer_get(object, key)
Get an integer field from a JSON object.
Definition: json.h:609
const char * ast_json_string_get(const struct ast_json *string)
Get the value of a JSON string.
Definition: json.c:283
const char * ast_json_object_iter_key(struct ast_json_iter *iter)
Get the key from an iterator.
Definition: json.c:451
struct ast_json * ast_json_object_get(struct ast_json *object, const char *key)
Get a field from a JSON object.
Definition: json.c:407
size_t ast_json_array_size(const struct ast_json *array)
Get the size of a JSON array.
Definition: json.c:366
#define AST_LIST_NEXT(elm, field)
Returns the next entry in the list after the given entry.
Definition: linkedlists.h:439
Asterisk module definitions.
@ AST_MODFLAG_LOAD_ORDER
Definition: module.h:331
#define ast_module_unref(mod)
Release a reference to the module.
Definition: module.h:483
#define ast_module_ref(mod)
Hold a reference to the module.
Definition: module.h:457
#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_SUCCESS
Definition: module.h:70
@ AST_MODULE_LOAD_DECLINE
Module has failed to load, may be in an inconsistent state.
Definition: module.h:78
Asterisk External Application Protocol API.
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:322
int ast_aeap_user_data_register(struct ast_aeap *aeap, const char *id, void *obj, ast_aeap_user_obj_cleanup cleanup)
Register a user data object.
Definition: aeap.c:150
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:136
void * ast_aeap_user_data_object_by_id(struct ast_aeap *aeap, const char *id)
Retrieve a registered user data object by its id.
Definition: aeap.c:174
int ast_aeap_send_msg(struct ast_aeap *aeap, struct ast_aeap_message *msg)
Send a message to an external application.
Definition: aeap.c:439
struct ast_variable * ast_aeap_custom_fields_get(const char *id)
Retrieve a list of custom configuration fields.
Definition: res_aeap.c:328
struct ast_sorcery * ast_aeap_sorcery(void)
Retrieve the AEAP sorcery object.
Definition: res_aeap.c:67
int ast_aeap_send_msg_tsx(struct ast_aeap *aeap, struct ast_aeap_tsx_params *params)
Send a transaction based message to an external application using the given parameters.
Definition: aeap.c:464
#define AEAP_CONFIG_CLIENT
Definition: res_aeap.h:35
int ast_aeap_send_binary(struct ast_aeap *aeap, const void *buf, uintmax_t size)
Send a binary data to an external application.
Definition: aeap.c:434
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:142
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:131
Asterisk External Application Protocol Message API.
struct ast_aeap_message * ast_aeap_message_create_error(const struct ast_aeap_message_type *type, const char *name, const char *id, const char *error_msg)
Create an Asterisk external application error response object.
const char * ast_aeap_message_id(const struct ast_aeap_message *message)
Retrieve a message id.
struct ast_aeap_message * ast_aeap_message_create_request(const struct ast_aeap_message_type *type, const char *name, const char *id, const void *params)
Create an Asterisk external application request object.
const char * ast_aeap_message_name(const struct ast_aeap_message *message)
Retrieve a message name.
const struct ast_aeap_message_type * ast_aeap_message_type_json
Asterisk external application JSON message type.
Definition: message_json.c:191
struct ast_aeap_message * ast_aeap_message_create_response(const struct ast_aeap_message_type *type, const char *name, const char *id, const void *params)
Create an Asterisk external application response object.
void * ast_aeap_message_data(struct ast_aeap_message *message)
Retrieve the core message data/body.
struct ao2_container * container
Definition: res_fax.c:501
static const struct ast_aeap_message_handler response_handlers[]
static int speech_aeap_engine_destroy(struct ast_speech *speech)
#define CONNECTION_TIMEOUT
static void speech_observer_loaded(const char *object_type)
static int load_engine(void *obj, void *arg, int flags)
static int matches_engine(void *obj, void *arg, int flags)
static int speech_aeap_engine_change(struct ast_speech *speech, const char *name, const char *value)
static struct ast_speech_result * speech_aeap_engine_get(struct ast_speech *speech)
static int handle_results(struct ast_aeap *aeap, struct ast_json_iter *iter, struct ast_speech_result **speech_results)
static int handle_setting(struct ast_aeap *aeap, struct ast_json_iter *iter, struct speech_setting *setting)
static const struct ast_sorcery_observer speech_observer
Observer for AEAP reloads.
static int handle_response_get(struct ast_aeap *aeap, struct ast_aeap_message *message, void *data)
#define SPEECH_PROTOCOL
static int should_unregister(const struct ast_speech_engine *engine, void *data)
static struct ast_speech_engine * speech_engine_alloc(const char *name)
static int speech_aeap_engine_get_setting(struct ast_speech *speech, const char *name, char *buf, size_t len)
static int unload_engine(void *obj, void *arg, int flags)
static int speech_aeap_get(struct ast_speech *speech, const char *param, void *data)
static int speech_aeap_engine_write(struct ast_speech *speech, void *data, int len)
static void ast_aeap_speech_on_error(struct ast_aeap *aeap)
static int handle_response_setup(struct ast_aeap *aeap, struct ast_aeap_message *message, void *data)
static const struct ast_aeap_message_handler request_handlers[]
static void speech_engine_destroy(void *obj)
static int speech_aeap_engine_create(struct ast_speech *speech, struct ast_format *format)
#define log_error(obj, fmt,...)
static struct ast_json * custom_fields_to_params(const struct ast_variable *variables)
static struct ast_aeap_params speech_aeap_params
static int handle_response_set(struct ast_aeap *aeap, struct ast_aeap_message *message, void *data)
static int speech_aeap_engine_start(struct ast_speech *speech)
static int speech_aeap_send_request(struct ast_aeap *aeap, const char *name, struct ast_json *json, void *data)
#define SPEECH_AEAP_VERSION
static int load_module(void)
static int speech_aeap_engine_dtmf(struct ast_speech *speech, const char *dtmf)
static int speech_aeap_engine_change_results_type(struct ast_speech *speech, enum ast_speech_results_type results_type)
static int unload_module(void)
static void speech_engine_alloc_and_register(const char *name, const struct ast_format_cap *formats)
static int handle_request_set(struct ast_aeap *aeap, struct ast_aeap_message *message, void *data)
static int speech_aeap_set(struct ast_speech *speech, const char *name, const char *value)
#define NULL
Definition: resample.c:96
Sorcery Data Access Layer API.
const char * ast_sorcery_object_get_id(const void *object)
Get the unique identifier of a sorcery object.
Definition: sorcery.c:2317
void ast_sorcery_observer_remove(const struct ast_sorcery *sorcery, const char *type, const struct ast_sorcery_observer *callbacks)
Remove an observer from a specific object type.
Definition: sorcery.c:2423
int ast_sorcery_observer_add(const struct ast_sorcery *sorcery, const char *type, const struct ast_sorcery_observer *callbacks)
Add an observer to a specific object type.
Definition: sorcery.c:2391
Generic Speech Recognition API.
struct ast_speech_engine * ast_speech_find_engine(const char *engine_name)
Retrieve a speech recognition engine.
Definition: res_speech.c:46
const char * ast_speech_results_type_to_string(enum ast_speech_results_type type)
Convert a speech results type to a string.
Definition: res_speech.c:294
struct ast_speech_engine * ast_speech_unregister2(const char *engine_name)
Unregister a speech recognition engine.
Definition: res_speech.c:352
void ast_speech_unregister_engines(int(*should_unregister)(const struct ast_speech_engine *engine, void *data), void *data, void(*on_unregistered)(void *obj))
Unregister all speech recognition engines told to by callback.
Definition: res_speech.c:380
int ast_speech_register(struct ast_speech_engine *engine)
Register a speech recognition engine.
Definition: res_speech.c:316
int ast_speech_change_state(struct ast_speech *speech, int state)
Change state of a speech structure.
Definition: res_speech.c:278
@ AST_SPEECH_STATE_DONE
Definition: speech.h:42
@ AST_SPEECH_STATE_READY
Definition: speech.h:40
ast_speech_results_type
Definition: speech.h:45
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:425
Generic container type.
An Asterisk external application message handler.
Definition: res_aeap.h:108
Asterisk external application base message.
Callbacks and other parameters used by an Asterisk external application object.
Definition: res_aeap.h:144
const struct ast_aeap_message_type * msg_type
Definition: res_aeap.h:152
const struct ast_aeap_message_handler * response_handlers
Definition: res_aeap.h:155
Parameters to be used when sending a transaction based message.
Definition: res_aeap.h:331
struct ast_aeap_message * msg
Definition: res_aeap.h:333
Definition: aeap.c:47
Format capabilities structure, holds formats + preference order + etc.
Definition: format_cap.c:54
Definition of a media format.
Definition: format.c:43
Iterator for JSON object key/values.
Abstract JSON element (object, array, string, int, ...).
struct ast_module * self
Definition: module.h:356
Interface for a sorcery object type observer.
Definition: sorcery.h:332
void(* loaded)(const char *object_type)
Callback for when an object type is loaded/reloaded.
Definition: sorcery.h:343
struct ast_format_cap * formats
Definition: speech.h:106
int(* start)(struct ast_speech *speech)
Definition: speech.h:96
int(* change_results_type)(struct ast_speech *speech, enum ast_speech_results_type results_type)
Definition: speech.h:102
struct ast_speech_result *(* get)(struct ast_speech *speech)
Definition: speech.h:104
int(* get_setting)(struct ast_speech *speech, const char *name, char *buf, size_t len)
Definition: speech.h:100
int(* destroy)(struct ast_speech *speech)
Definition: speech.h:82
int(* dtmf)(struct ast_speech *speech, const char *dtmf)
Definition: speech.h:94
int(* change)(struct ast_speech *speech, const char *name, const char *value)
Definition: speech.h:98
char * name
Definition: speech.h:78
int(* create)(struct ast_speech *speech, struct ast_format *format)
Definition: speech.h:80
int(* write)(struct ast_speech *speech, void *data, int len)
Definition: speech.h:92
void * data
Definition: speech.h:66
struct ast_speech_engine * engine
Definition: speech.h:72
struct ast_speech_result * results
Definition: speech.h:68
Structure for variables, used for configurations and for channel variables.
struct ast_variable * next
Definition: file.c:69
const char * value
const char * name
const char * param
int value
Definition: syslog.c:37
#define ARRAY_LEN(a)
Definition: utils.h:666