43 #define SPEECH_AEAP_VERSION "0.1.0"
44 #define SPEECH_PROTOCOL "speech_to_text"
46 #define CONNECTION_TIMEOUT 2000
48 #define log_error(obj, fmt, ...) \
49 ast_log(LOG_ERROR, "AEAP speech (%p): " fmt "\n", obj, ##__VA_ARGS__)
65 for (i = variables; i; i = i->
next) {
66 if (i->
name[0] ==
'@' && i->
name[1]) {
90 static int speech_aeap_send_request(
struct ast_aeap *aeap,
const char *name,
106 if (!tsx_params.
msg) {
130 static int speech_aeap_get(
struct ast_speech *speech,
const char *param,
void *data)
137 return speech_aeap_send_request(speech->
data,
162 static int speech_aeap_set(
struct ast_speech *speech,
const char *name,
const char *value)
169 return speech_aeap_send_request(speech->
data,
170 "set",
ast_json_pack(
"{s:{s:s}}",
"params", name, value), NULL);
190 log_error(aeap,
"Unable to 'get' speech setting for '%s'", setting->param);
196 log_error(aeap,
"No value for speech setting '%s'", setting->param);
213 if (!json_results || !speech_results) {
214 log_error(aeap,
"Unable to 'get' speech results");
219 if (!(result =
ast_calloc(1,
sizeof(*result)))) {
229 if (*speech_results) {
231 *speech_results = result;
233 *speech_results = result;
265 log_error(aeap,
"no 'get' parameters returned");
270 return handle_results(aeap, iter, data);
273 return handle_setting(aeap, iter, data);
280 const char *codec_name;
283 log_error(aeap,
"no 'format' set");
288 log_error(aeap,
"no 'setup' object returned");
294 log_error(aeap,
"no 'setup' codecs available");
308 {
"setup", handle_response_setup },
309 {
"get", handle_response_get },
310 {
"set", handle_response_set },
316 const char *error_msg = NULL;
320 error_msg =
"no parameter(s) requested";
325 error_msg =
"no associated speech object";
326 }
else if (handle_results(aeap, iter, &speech->
results)) {
327 error_msg =
"unable to handle results";
332 error_msg =
"can only set 'results'";
336 log_error(aeap,
"set - %s", error_msg);
350 {
"set", handle_request_set },
359 static void ast_aeap_speech_on_error(
struct ast_aeap *aeap)
363 ast_log(LOG_ERROR,
"aeap generated error with no associated speech object");
372 .response_handlers_size = ARRAY_LEN(response_handlers),
374 .request_handlers_size = ARRAY_LEN(request_handlers),
375 .on_error = ast_aeap_speech_on_error,
410 speech->
engine->
name, &speech_aeap_params, CONNECTION_TIMEOUT);
423 json =
ast_json_pack(
"{s:s,s:[{s:s}],s:o*}",
"version", SPEECH_AEAP_VERSION,
"codecs",
434 if (speech_aeap_send_request(speech->
data,
"setup", json, format)) {
448 static int speech_aeap_engine_destroy(
struct ast_speech *speech)
451 ao2_cleanup(speech->
data);
458 static int speech_aeap_engine_write(
struct ast_speech *speech,
void *data,
int len)
463 static int speech_aeap_engine_dtmf(
struct ast_speech *speech,
const char *dtmf)
465 return speech_aeap_set(speech,
"dtmf", dtmf);
468 static int speech_aeap_engine_start(
struct ast_speech *speech)
475 static int speech_aeap_engine_change(
struct ast_speech *speech,
const char *name,
const char *value)
477 return speech_aeap_set(speech, name, value);
480 static int speech_aeap_engine_get_setting(
struct ast_speech *speech,
const char *name,
481 char *buf,
size_t len)
489 return speech_aeap_get(speech, name, &setting);
492 static int speech_aeap_engine_change_results_type(
struct ast_speech *speech,
493 enum ast_speech_results_type results_type)
495 return speech_aeap_set(speech,
"results_type",
507 if (speech_aeap_get(speech,
"results", &results)) {
514 static void speech_engine_destroy(
void *obj)
519 ast_free(engine->
name);
529 ast_log(LOG_ERROR,
"AEAP speech: unable create engine '%s'\n", name);
539 engine->
create = speech_aeap_engine_create;
540 engine->
destroy = speech_aeap_engine_destroy;
541 engine->
write = speech_aeap_engine_write;
542 engine->
dtmf = speech_aeap_engine_dtmf;
543 engine->
start = speech_aeap_engine_start;
544 engine->
change = speech_aeap_engine_change;
545 engine->
get_setting = speech_aeap_engine_get_setting;
547 engine->
get = speech_aeap_engine_get;
558 engine = speech_engine_alloc(name);
564 formats, AST_MEDIA_TYPE_AUDIO)) {
565 ast_log(LOG_WARNING,
"AEAP speech: Unable to add engine '%s' formats\n", name);
571 ast_log(LOG_WARNING,
"AEAP speech: Unable to register engine '%s'\n", name);
576 #ifdef TEST_FRAMEWORK
578 static void speech_engine_alloc_and_register2(
const char *name,
const char *codec_names)
582 engine = speech_engine_alloc(name);
588 ast_log(LOG_WARNING,
"AEAP speech: Unable to add engine '%s' codecs\n", name);
594 ast_log(LOG_WARNING,
"AEAP speech: Unable to register engine '%s'\n", name);
601 static int unload_engine(
void *obj,
void *arg,
int flags)
610 static int load_engine(
void *obj,
void *arg,
int flags)
625 ast_log(LOG_ERROR,
"AEAP speech: unable to allocate default engine format for '%s'\n",
id);
632 speech_engine_alloc_and_register(
id, formats);
642 speech_engine_alloc_and_register(
id, formats);
647 static int matches_engine(
void *obj,
void *arg,
int flags)
658 if (engine->
create != speech_aeap_engine_create) {
663 #ifdef TEST_FRAMEWORK
664 if (!strcmp(
"_aeap_test_speech_", engine->
name)) {
670 obj =
ao2_callback(data, 0, matches_engine, (
void*)engine);
681 static void speech_observer_loaded(
const char *object_type)
685 if (strcmp(object_type, AEAP_CONFIG_CLIENT)) {
707 .
loaded = speech_observer_loaded,
710 static int unload_module(
void)
714 #ifdef TEST_FRAMEWORK
729 static int load_module(
void)
750 #ifdef TEST_FRAMEWORK
751 speech_engine_alloc_and_register2(
"_aeap_test_speech_",
"ulaw");
757 AST_MODULE_INFO(
ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER,
"Asterisk External Application Speech Engine",
758 .support_level = AST_MODULE_SUPPORT_CORE,
760 .unload = unload_module,
762 .requires =
"res_speech,res_aeap",
struct ast_variable * next
Asterisk External Application Protocol API.
Callbacks and other parameters used by an Asterisk external application object.
Asterisk main include file. File version handling, generic pbx functions.
int(* destroy)(struct ast_speech *speech)
struct ast_json * ast_json_pack(char const *format,...)
Helper for creating complex JSON values.
Generic Speech Recognition API.
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
int(* create)(struct ast_speech *speech, struct ast_format *format)
int(* change)(struct ast_speech *speech, const char *name, const char *value)
Asterisk External Application Protocol Message API.
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.
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.
struct ast_speech_engine * ast_speech_unregister2(const char *engine_name)
Unregister a speech recognition engine.
Iterator for JSON object key/values.
const struct ast_aeap_message_handler * request_handlers
#define ao2_callback(c, flags, cb_fn, arg)
ao2_callback() is a generic function that applies cb_fn() to all objects in a container, as described below.
struct ast_json_iter * ast_json_object_iter(struct ast_json *object)
Get an iterator pointing to the first field in a JSON object.
void __ao2_cleanup(void *obj)
void * ast_aeap_message_data(struct ast_aeap_message *message)
Retrieve the core message data/body.
Structure for variables, used for configurations and for channel variables.
#define AST_LIST_NEXT(elm, field)
Returns the next entry in the list after the given entry.
int ast_speech_register(struct ast_speech_engine *engine)
Register a speech recognition engine.
const struct ast_aeap_message_type * msg_type
#define ao2_t_alloc_options(data_size, destructor_fn, options, debug_msg)
Allocate and initialize an object.
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.
#define ast_strdup(str)
A wrapper for strdup()
struct ast_sorcery * ast_aeap_sorcery(void)
Retrieve the AEAP sorcery object.
void * ast_aeap_user_data_object_by_id(struct ast_aeap *aeap, const char *id)
Retrieve a registered user data object by its id.
int(* start)(struct ast_speech *speech)
#define ast_json_object_integer_get(object, key)
Get an integer field from a JSON object.
Parameters to be used when sending a transaction based message.
int ast_json_object_set(struct ast_json *object, const char *key, struct ast_json *value)
Set a field in a JSON object.
const char * ast_aeap_message_id(const struct ast_aeap_message *message)
Retrieve a message id.
Configuration File Parser.
int ast_aeap_send_msg(struct ast_aeap *aeap, struct ast_aeap_message *msg)
Send a message to an external application.
Asterisk JSON abstraction layer.
struct ast_json * ast_json_object_iter_value(struct ast_json_iter *iter)
Get the value from an iterator.
struct ast_json * ast_json_string_create(const char *value)
Construct a JSON string from value.
int ast_speech_change_state(struct ast_speech *speech, int state)
Change state of a speech structure.
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
#define ast_json_object_string_get(object, key)
Get a string field from a JSON object.
struct ast_format_cap * formats
const char * ast_sorcery_object_get_id(const void *object)
Get the unique identifier of a sorcery object.
const char * ast_json_string_get(const struct ast_json *string)
Get the value of a JSON string.
int(* change_results_type)(struct ast_speech *speech, enum ast_speech_results_type results_type)
struct ao2_container * container
struct ast_speech_engine * engine
const char * ast_json_object_iter_key(struct ast_json_iter *iter)
Get the key from an iterator.
const char * ast_aeap_message_name(const struct ast_aeap_message *message)
Retrieve a message name.
struct ast_speech_result * results
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.
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.
struct ast_speech_engine * ast_speech_find_engine(const char *engine_name)
Retrieve a speech recognition engine.
struct ast_speech_result *(* get)(struct ast_speech *speech)
struct ast_variable * ast_aeap_custom_fields_get(const char *id)
Retrieve a list of custom configuration fields.
int(* write)(struct ast_speech *speech, void *data, int len)
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.
Interface for a sorcery object type observer.
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.
Asterisk external application base message.
#define ast_module_ref(mod)
Hold a reference to the module.
An Asterisk external application message handler.
#define ast_calloc(num, len)
A wrapper for calloc()
Module has failed to load, may be in an inconsistent state.
const char * ast_speech_results_type_to_string(enum ast_speech_results_type type)
Convert a speech results type to a string.
void(* loaded)(const char *object_type)
Callback for when an object type is loaded/reloaded.
#define ast_module_unref(mod)
Release a reference to the module.
struct ast_json * ast_json_object_create(void)
Create a new JSON object.
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.
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.
struct ast_json * ast_json_object_get(struct ast_json *object, const char *key)
Get a field from a JSON object.
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
size_t ast_json_array_size(const struct ast_json *array)
Get the size of a JSON array.
int(* dtmf)(struct ast_speech *speech, const char *dtmf)
struct ast_aeap_message * msg
Abstract JSON element (object, array, string, int, ...).
const struct ast_aeap_message_handler * response_handlers
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 struct ast_format_cap * ast_aeap_client_config_codecs(const struct ast_aeap_client_config *cfg)
Retrieve codec capabilities from the configuration.
struct ao2_container * ast_aeap_client_configs_get(const char *protocol)
Retrieve a listing of all client configuration objects by protocol.
const struct ast_aeap_message_type * ast_aeap_message_type_json
Asterisk external application JSON message type.
#define ASTERISK_GPL_KEY
The text the key() function should return.
Asterisk module definitions.
static const struct ast_sorcery_observer speech_observer
Observer for AEAP reloads.
struct ast_json * ast_json_array_get(const struct ast_json *array, size_t index)
Get an element from an array.
int ast_aeap_send_binary(struct ast_aeap *aeap, const void *buf, uintmax_t size)
Send a binary data to an external application.
int(* get_setting)(struct ast_speech *speech, const char *name, char *buf, size_t len)
Sorcery Data Access Layer API.