diff options
author | file <file@f38db490-d61c-443f-a65b-d21fe96a405b> | 2006-04-10 23:29:50 +0000 |
---|---|---|
committer | file <file@f38db490-d61c-443f-a65b-d21fe96a405b> | 2006-04-10 23:29:50 +0000 |
commit | 483e826311511fc52ec00a0155582a73fd2db625 (patch) | |
tree | 165b92004e41c726c99721800866bd38eb63faf7 /channel.c | |
parent | 31b2a51bfb374fb3789b8b69abf2e0f428935d3c (diff) |
Presenting a revised data stores and oh my, a generic speech recognition API! I wonder what we can do with this now...
git-svn-id: http://svn.digium.com/svn/asterisk/trunk@18979 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'channel.c')
-rw-r--r-- | channel.c | 124 |
1 files changed, 124 insertions, 0 deletions
@@ -653,6 +653,7 @@ struct ast_channel *ast_channel_alloc(int needqueue) headp = &tmp->varshead; ast_mutex_init(&tmp->lock); AST_LIST_HEAD_INIT_NOLOCK(headp); + AST_LIST_HEAD_INIT_NOLOCK(&tmp->datastores); strcpy(tmp->context, "default"); ast_string_field_set(tmp, language, defaultlanguage); strcpy(tmp->exten, "s"); @@ -928,6 +929,7 @@ void ast_channel_free(struct ast_channel *chan) struct ast_var_t *vardata; struct ast_frame *f, *fp; struct varshead *headp; + struct ast_datastore *datastore = NULL; char name[AST_CHANNEL_NAME]; headp=&chan->varshead; @@ -981,6 +983,18 @@ void ast_channel_free(struct ast_channel *chan) ast_frfree(fp); } + /* Get rid of each of the data stores on the channel */ + AST_LIST_LOCK(&chan->datastores); + AST_LIST_TRAVERSE_SAFE_BEGIN(&chan->datastores, datastore, list) { + /* Remove from the list */ + AST_LIST_REMOVE_CURRENT(&chan->datastores, list); + /* Free the data store */ + ast_channel_datastore_free(datastore); + } + AST_LIST_TRAVERSE_SAFE_END + AST_LIST_UNLOCK(&chan->datastores); + AST_LIST_HEAD_DESTROY(&chan->datastores); + /* loop over the variables list, freeing all data and deleting list items */ /* no need to lock the list, as the channel is already locked */ @@ -994,6 +1008,111 @@ void ast_channel_free(struct ast_channel *chan) ast_device_state_changed_literal(name); } +struct ast_datastore *ast_channel_datastore_alloc(const struct ast_datastore_info *info, char *uid) +{ + struct ast_datastore *datastore = NULL; + + /* Make sure we at least have type so we can identify this */ + if (info == NULL) { + return NULL; + } + + /* Allocate memory for datastore and clear it */ + datastore = ast_calloc(1, sizeof(*datastore)); + if (datastore == NULL) { + return NULL; + } + + datastore->info = info; + + if (uid != NULL) { + datastore->uid = ast_strdup(uid); + } + + return datastore; +} + +int ast_channel_datastore_free(struct ast_datastore *datastore) +{ + int res = 0; + + /* Using the destroy function (if present) destroy the data */ + if (datastore->info->destroy != NULL && datastore->data != NULL) { + datastore->info->destroy(datastore->data); + datastore->data = NULL; + } + + /* Free allocated UID memory */ + if (datastore->uid != NULL) { + free(datastore->uid); + datastore->uid = NULL; + } + + /* Finally free memory used by ourselves */ + free(datastore); + datastore = NULL; + + return res; +} + +int ast_channel_datastore_add(struct ast_channel *chan, struct ast_datastore *datastore) +{ + int res = 0; + + AST_LIST_LOCK(&chan->datastores); + AST_LIST_INSERT_HEAD(&chan->datastores, datastore, list); + AST_LIST_UNLOCK(&chan->datastores); + + return res; +} + +int ast_channel_datastore_remove(struct ast_channel *chan, struct ast_datastore *datastore) +{ + struct ast_datastore *datastore2 = NULL; + int res = -1; + + /* Find our position and remove ourselves */ + AST_LIST_LOCK(&chan->datastores); + AST_LIST_TRAVERSE_SAFE_BEGIN(&chan->datastores, datastore2, list) { + if (datastore2 == datastore) { + AST_LIST_REMOVE_CURRENT(&chan->datastores, list); + res = 0; + break; + } + } + AST_LIST_TRAVERSE_SAFE_END + AST_LIST_UNLOCK(&chan->datastores); + + return res; +} + +struct ast_datastore *ast_channel_datastore_find(struct ast_channel *chan, const struct ast_datastore_info *info, char *uid) +{ + struct ast_datastore *datastore = NULL; + + if (info == NULL) + return NULL; + + AST_LIST_LOCK(&chan->datastores); + AST_LIST_TRAVERSE_SAFE_BEGIN(&chan->datastores, datastore, list) { + if (datastore->info == info) { + if (uid != NULL && datastore->uid != NULL) { + if (!strcasecmp(uid, datastore->uid)) { + /* Matched by type AND uid */ + break; + } + } else { + /* Matched by type at least */ + break; + } + } + } + AST_LIST_TRAVERSE_SAFE_END + AST_LIST_UNLOCK(&chan->datastores); + + return datastore; +} + int ast_channel_spy_add(struct ast_channel *chan, struct ast_channel_spy *spy) { if (!ast_test_flag(spy, CHANSPY_FORMAT_AUDIO)) { @@ -3048,6 +3167,11 @@ int ast_do_masquerade(struct ast_channel *original) if (x != AST_GENERATOR_FD) original->fds[x] = clone->fds[x]; } + /* Move data stores over */ + if (AST_LIST_FIRST(&clone->datastores)) + AST_LIST_INSERT_TAIL(&original->datastores, AST_LIST_FIRST(&clone->datastores), list); + AST_LIST_HEAD_INIT_NOLOCK(&clone->datastores); + clone_variables(original, clone); AST_LIST_HEAD_INIT_NOLOCK(&clone->varshead); /* Presense of ADSI capable CPE follows clone */ |