Asterisk - The Open Source Telephony Project GIT-master-7805f28
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Macros Modules Pages
channelstorage.c
Go to the documentation of this file.
1/*
2 * Asterisk -- An open source telephony toolkit.
3 *
4 * Copyright (C) 2024, Sangoma Technologies Corporation
5 *
6 * George Joseph <gjoseph@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#include "asterisk.h"
20#include "asterisk/options.h"
21#include "channelstorage.h"
22
24
27{
28 if (storage_drivers.elems == NULL) {
30 }
32}
33
35 const char *driver_name)
36{
37 int i;
38
39 for (i = 0; i < AST_VECTOR_SIZE(&storage_drivers); i++) {
40 const struct ast_channelstorage_driver *dt =
42 if (strcasecmp(driver_name, dt->driver_name) == 0) {
43 return dt;
44 }
45 }
46 return NULL;
47}
48
50 const struct ast_channelstorage_driver *storage_driver,
51 const char *instance_name)
52{
53 struct ast_channelstorage_instance *storage_instance = NULL;
54
55 storage_instance = storage_driver->open(instance_name);
56 if (!storage_instance) {
57 ast_log(LOG_ERROR, "Failed to open channel storage driver '%s'\n",
58 storage_driver->driver_name);
59 return NULL;
60 }
61
62 return storage_instance;
63};
64
66{
67 CHANNELSTORAGE_API(storage_instance, close);
68};
69
70int channelstorage_exten_cb(void *obj, void *arg, void *data, int flags)
71{
72 struct ast_channel *chan = (struct ast_channel *)obj;
73 const char *context = (const char *)arg;
74 const char *exten = (const char *)data;
75 int ret = 0;
76
77 ao2_lock(chan);
78 if (strcasecmp(ast_channel_context(chan), context) == 0 &&
79 strcasecmp(ast_channel_exten(chan), exten) == 0) {
80 ret = CMP_MATCH | ((flags & OBJ_MULTIPLE) ? 0 : CMP_STOP);
81 }
82 ao2_unlock(chan);
83
84 return ret;
85}
86
88 const char *exten, const char *context)
89{
90 char *l_exten = (char *) exten;
91 char *l_context = (char *) context;
92
93 return CHANNELSTORAGE_API(driver, callback, channelstorage_exten_cb, l_context, l_exten, 0);
94}
95
96int channelstorage_name_cb(void *obj, void *arg, void *data, int flags)
97{
98 struct ast_channel *chan = obj;
99 const char *name = arg;
100 size_t name_len = *(size_t *) data;
101 int ret = 0;
102
103 if (name_len == 0) {
104 if(strcasecmp(ast_channel_name(chan), name) == 0) {
105 ret = CMP_MATCH | ((flags & OBJ_MULTIPLE) ? 0 : CMP_STOP);
106 }
107 } else {
108 if (strncasecmp(ast_channel_name(chan), name, name_len) == 0) {
109 ret = CMP_MATCH | ((flags & OBJ_MULTIPLE) ? 0 : CMP_STOP);
110 }
111 }
112
113 return ret;
114}
115
117 const char *name)
118{
119 return CHANNELSTORAGE_API(driver, get_by_name_prefix_or_uniqueid, name, 0);
120}
121
123 const char *name, size_t name_len)
124{
125 struct ast_channel *chan = NULL;
126
127 chan = CHANNELSTORAGE_API(driver, get_by_name_prefix, name, name_len);
128 if (chan) {
129 return chan;
130 }
131
132 if (name_len == 0) {
133 chan = CHANNELSTORAGE_API(driver, get_by_uniqueid, name);
134 }
135
136 return chan;
137}
138
139int channelstorage_uniqueid_cb(void *obj, void *arg, void *data, int flags)
140{
141 struct ast_channel *chan = obj;
142 char *uniqueid = arg;
143 int ret = 0;
144
145 if(strcasecmp(ast_channel_uniqueid(chan), uniqueid) == 0) {
146 ret = CMP_MATCH | CMP_STOP;
147 }
148
149 return ret;
150}
151
153 const char *uniqueid)
154{
156}
157
158#ifdef TEST_FRAMEWORK
159#include "asterisk/test.h"
160#include "channel_private.h"
161
162static void mock_channel_destructor(void *obj)
163{
164 struct ast_channel *chan = obj;
166}
167
168struct test_info {
169 struct ast_test *test;
170 struct ast_channelstorage_instance *storage_instance;
171 enum ast_test_result_state res;
172};
173
174static void *test_storage_thread(void *data)
175{
176 struct test_info *test_info = data;
177 struct ast_test *test = test_info->test;
178 struct ast_channelstorage_instance *storage_instance = test_info->storage_instance;
179 struct ast_channel *mock_channel;
181 int i;
182 struct timeval start;
183 struct timeval end;
184 int64_t elapsed;
185 char search1[128];
186 char search2[128];
187 int rc = 0;
188 long int rand = ast_random();
189 struct ast_channel_iterator *iter;
190 int collen = 25;
191 int CHANNEL_COUNT = 500;
192 struct ast_cli_args *cli_args = ast_test_get_cli_args(test);
193 struct ast_channel **test_channels;
194
195 for (i = 0; i < cli_args->argc; i++) {
196 if (ast_begins_with(cli_args->argv[i], "channel-count=")) {
197 sscanf(cli_args->argv[i], "channel-count=%d", &CHANNEL_COUNT);
198 }
199 }
200 test_channels = ast_calloc(CHANNEL_COUNT, sizeof(*test_channels));
201 ast_test_status_update(test, "%*s: %8d\n", collen, "Channel Count", CHANNEL_COUNT);
202
203 start = ast_tvnow();
204 for (i = 0; i < CHANNEL_COUNT; i++) {
205 test_channels[i] = ao2_alloc(sizeof(*mock_channel), mock_channel_destructor);
206 ast_test_validate_cleanup(test, test_channels[i], res, done);
207 ast_string_field_init(test_channels[i], 128);
208 ast_string_field_build(test_channels[i], name, "TestChannel-%ld-%04d-something", rand, i);
209 snprintf(test_channels[i]->context, AST_MAX_CONTEXT, "TestContext-%ld-%04d", rand, i % 100);
210 snprintf(test_channels[i]->exten, AST_MAX_EXTENSION, "TestExten-%ld-%04d", rand, i % 10);
211 snprintf(test_channels[i]->uniqueid.unique_id, AST_MAX_UNIQUEID, "TestUniqueid-%ld-%04d-something", rand, i);
212 rc = CHANNELSTORAGE_API(storage_instance, insert, test_channels[i], 0, 1);
213 ast_test_validate_cleanup_custom(test, rc == 0, res, done, "Unable to insert channel %s\n", test_channels[i]->name);
214 }
215 end = ast_tvnow();
216 elapsed = ast_tvdiff_us(end, start);
217 i = CHANNELSTORAGE_API(storage_instance, active_channels);
218 ast_test_status_update(test, "%*s: %8ld\n", collen, "create channels", elapsed);
219 ast_test_validate_cleanup(test, i == CHANNEL_COUNT, res, done);
220
221 start = ast_tvnow();
222 for (i = 0; i < CHANNEL_COUNT; i++) {
223 sprintf(search1, "testchannel-%ld-%04d-something", rand, i);
224 mock_channel = CHANNELSTORAGE_API(storage_instance, get_by_name_prefix_or_uniqueid, search1, 0);
225 ast_test_validate_cleanup(test, mock_channel, res, done);
226 ast_test_validate_cleanup(test, mock_channel == test_channels[i], res, done);
227 ast_test_validate_cleanup(test,
228 strcasecmp(ast_channel_name(mock_channel), search1) == 0, res, done);
229 ast_channel_unref(mock_channel);
230 }
231 end = ast_tvnow();
232 elapsed = ast_tvdiff_us(end, start);
233 ast_test_status_update(test, "%*s: %8ld\n", collen, "by name exact", elapsed);
234
235 start = ast_tvnow();
236 for (i = 0; i < CHANNEL_COUNT; i++) {
237 sprintf(search1, "TestUniqueid-%ld-%04d-something", rand, i);
238 mock_channel = CHANNELSTORAGE_API(storage_instance, get_by_uniqueid, search1);
239 ast_test_validate_cleanup(test, mock_channel, res, done);
240 ast_channel_unref(mock_channel);
241 }
242 end = ast_tvnow();
243 elapsed = ast_tvdiff_us(end, start);
244 ast_test_status_update(test, "%*s: %8ld\n", collen, "by uniqueid exact", elapsed);
245
246 start = ast_tvnow();
247 for (i = 0; i < CHANNEL_COUNT; i++) {
248 sprintf(search1, "TestUniqueid-%ld-%04d-something", rand, i);
249 mock_channel = CHANNELSTORAGE_API(storage_instance, get_by_name_prefix_or_uniqueid, search1, 0);
250 ast_test_validate_cleanup(test, mock_channel, res, done);
251 ast_channel_unref(mock_channel);
252 }
253 end = ast_tvnow();
254 elapsed = ast_tvdiff_us(end, start);
255 ast_test_status_update(test, "%*s: %8ld\n", collen, "by uniqueid via nm", elapsed);
256
257 start = ast_tvnow();
258 for (i = 0; i < CHANNEL_COUNT; i++) {
259 sprintf(search1, "TestChannel-%ld-%04d", rand, i);
260 mock_channel = CHANNELSTORAGE_API(storage_instance, get_by_name_prefix_or_uniqueid, search1, strlen(search1));
261 ast_test_validate_cleanup(test, mock_channel, res, done);
262 ast_channel_unref(mock_channel);
263 }
264 end = ast_tvnow();
265 elapsed = ast_tvdiff_us(end, start);
266 ast_test_status_update(test, "%*s: %8ld\n", collen, "by name prefix", elapsed);
267
268 start = ast_tvnow();
269 for (i = 0; i < CHANNEL_COUNT; i++) {
270 sprintf(search1, "TestContext-%ld-%04d", rand, i % 100);
271 sprintf(search2, "TestExten-%ld-%04d", rand, i % 10);
272 mock_channel = CHANNELSTORAGE_API(storage_instance, get_by_exten, search2, search1);
273 ast_test_validate_cleanup(test, mock_channel, res, done);
274 ast_channel_unref(mock_channel);
275 }
276 end = ast_tvnow();
277 elapsed = ast_tvdiff_us(end, start);
278 ast_test_status_update(test, "%*s: %8ld\n", collen, "by context/exten", elapsed);
279
280#if 0
281 start = ast_tvnow();
282 for (i = 0; i < CHANNEL_COUNT; i++) {
283 sprintf(search1, "TestChannel-%ld-%04d-something", rand, i);
284 mock_channel = CHANNELSTORAGE_API(storage_instance, get_by_name_or_uniqueid, search1);
285 ast_test_validate_cleanup(test, mock_channel, res, done);
286
287 CHANNELSTORAGE_API(storage_instance, wrlock);
288
289 sprintf(mock_channel->context, "TestXXContext-%ld-%04d", rand, i);
290 sprintf(search1, "TestContext-%ld-%04d", rand, i);
291
292 rc = CHANNELSTORAGE_API(storage_instance, update, mock_channel,
293 AST_CHANNELSTORAGE_UPDATE_CONTEXT, search1, mock_channel->context, 0);
294 ast_test_validate_cleanup(test, rc == 0, res, done);
295
296 sprintf(mock_channel->exten, "TestXXExten-%ld-%04d", rand, i);
297 sprintf(search2, "TestExten-%ld-%04d", rand, i);
298
299 rc = CHANNELSTORAGE_API(storage_instance, update, mock_channel,
300 AST_CHANNELSTORAGE_UPDATE_EXTEN, search2, mock_channel->exten, 0);
301 CHANNELSTORAGE_API(storage_instance, unlock);
302
303 ast_test_validate_cleanup(test, rc == 0, res, done);
304
305 ast_channel_unref(mock_channel);
306 }
307 end = ast_tvnow();
308 elapsed = ast_tvdiff_us(end, start);
309 ast_test_status_update(test, "%*s: %8ld\n", collen, "update", elapsed);
310
311 start = ast_tvnow();
312 for (i = 0; i < CHANNEL_COUNT; i++) {
313 sprintf(search1, "TestXXContext-%ld-%04d", rand, i);
314 sprintf(search2, "TestXXExten-%ld-%04d", rand, i);
315 mock_channel = CHANNELSTORAGE_API(storage_instance, get_by_exten, search2, search1);
316 ast_test_validate_cleanup(test, mock_channel, res, done);
317 ast_channel_unref(mock_channel);
318 }
319 end = ast_tvnow();
320 elapsed = ast_tvdiff_us(end, start);
321 ast_test_status_update(test, "%*s: %8ld\n", collen, "by context/exten2", elapsed);
322
323 start = ast_tvnow();
324 for (i = 0; i < CHANNEL_COUNT; i++) {
325 sprintf(search1, "TestChannel-%ld-%04d-something", rand, i);
326 mock_channel = CHANNELSTORAGE_API(storage_instance, get_by_name_or_uniqueid, search1);
327 ast_test_validate_cleanup(test, mock_channel, res, done);
328 sprintf(search2, "TestXXChannel-%ld-%04d", rand, i);
329 rc = CHANNELSTORAGE_API(storage_instance, update, mock_channel,
330 AST_CHANNELSTORAGE_UPDATE_NAME, search1, search2, 1);
331 ast_channel_unref(mock_channel);
332 ast_test_validate_cleanup(test, rc == 0, res, done);
333 }
334 end = ast_tvnow();
335 elapsed = ast_tvdiff_us(end, start);
336 ast_test_status_update(test, "%*s: %8ld\n", collen, "change name", elapsed);
337
338 start = ast_tvnow();
339 for (i = 0; i < CHANNEL_COUNT; i++) {
340 sprintf(search1, "TestXXChannel-%ld-%04d", rand, i);
341 mock_channel = CHANNELSTORAGE_API(storage_instance, get_by_name_or_uniqueid, search1);
342 ast_test_validate_cleanup_custom(test, mock_channel, res, done,"Channel %s not found\n", search1);
343 ast_channel_unref(mock_channel);
344 }
345 end = ast_tvnow();
346 elapsed = ast_tvdiff_us(end, start);
347 ast_test_status_update(test, "%*s: %8ld\n", collen, "by name exact2", elapsed);
348#endif
349
350 i = 0;
351 start = ast_tvnow();
352 iter = CHANNELSTORAGE_API(storage_instance, iterator_all_new);
353 for (; (mock_channel = CHANNELSTORAGE_API(storage_instance, iterator_next, iter));
354 ast_channel_unref(mock_channel)) {
355 i++;
356 }
357 CHANNELSTORAGE_API(storage_instance, iterator_destroy, iter);
358 end = ast_tvnow();
359 elapsed = ast_tvdiff_us(end, start);
360 ast_test_status_update(test, "%*s: %8ld\n", collen, "iter all chan", elapsed);
361 ast_test_validate_cleanup_custom(test, i == CHANNEL_COUNT, res, done,
362 "Expected %d channels, got %d, in container: %d\n", CHANNEL_COUNT, i,
363 CHANNELSTORAGE_API(storage_instance, active_channels));
364
365 i = 0;
366 start = ast_tvnow();
367 sprintf(search1, "TestChannel-%ld-%03d", rand, (CHANNEL_COUNT - 11) / 10);
368 iter = CHANNELSTORAGE_API(storage_instance, iterator_by_name_new, search1, strlen(search1));
369 ast_test_validate_cleanup(test, iter != NULL, res, done);
370 for (; (mock_channel = CHANNELSTORAGE_API(storage_instance, iterator_next, iter));
371 ast_channel_unref(mock_channel)) {
372 ast_test_validate_cleanup_custom(test, strncmp(search1,
373 ast_channel_name(mock_channel), strlen(search1)) == 0, res, done, "Expected %s got %s\n",
374 search1, ast_channel_name(mock_channel));
375 i++;
376 }
377 CHANNELSTORAGE_API(storage_instance, iterator_destroy, iter);
378 end = ast_tvnow();
379 elapsed = ast_tvdiff_us(end, start);
380 ast_test_status_update(test, "%*s: %8ld\n", collen, "iter 10 partial name", elapsed);
381 ast_test_validate_cleanup_custom(test, i == 10, res, done,
382 "Expected %d channels, got %d, in container: %d\n", 10, i,
383 CHANNELSTORAGE_API(storage_instance, active_channels));
384
385 i = 0;
386 start = ast_tvnow();
387 sprintf(search1, "TestContext-%ld-%04d", rand, 50);
388 sprintf(search2, "TestExten-%ld-%04d", rand, 0);
389 iter = CHANNELSTORAGE_API(storage_instance, iterator_by_exten_new, search2, search1);
390 ast_test_validate_cleanup(test, iter != NULL, res, done);
391 for (; (mock_channel = CHANNELSTORAGE_API(storage_instance, iterator_next, iter));
392 ast_channel_unref(mock_channel)) {
393 ast_test_validate_cleanup_custom(test,
394 (strcmp(search1, mock_channel->context) == 0 &&
395 strcmp(search2, mock_channel->exten) == 0), res, done, "Expected %s-%s got %s-%s\n",
396 search1, search2, mock_channel->context, mock_channel->exten);
397 i++;
398 }
399 CHANNELSTORAGE_API(storage_instance, iterator_destroy, iter);
400 end = ast_tvnow();
401 elapsed = ast_tvdiff_us(end, start);
402 ast_test_status_update(test, "%*s: %8ld\n", collen, "iter context/exten", elapsed);
403 ast_test_validate_cleanup_custom(test, i == (CHANNEL_COUNT / 100), res, done,
404 "Expected %d channels, got %d, in container: %d\n", (CHANNEL_COUNT / 100), i,
405 CHANNEL_COUNT);
406
407done:
408 CHANNELSTORAGE_API(storage_instance, unlock);
409
410 start = ast_tvnow();
411 for (i = 0; i < CHANNEL_COUNT; i++) {
412 if (test_channels[i]) {
413 rc = CHANNELSTORAGE_API(storage_instance, remove, test_channels[i], 0);
414 ast_channel_unref(test_channels[i]);
415 test_channels[i] = NULL;
416 }
417 }
418 end = ast_tvnow();
419 elapsed = ast_tvdiff_us(end, start);
420 ast_test_status_update(test, "%*s: %8ld\n", collen, "del all channels", elapsed);
421 ast_test_validate_cleanup(test, i == CHANNEL_COUNT, res, done);
422 rc = CHANNELSTORAGE_API(storage_instance, active_channels);
423 ast_test_validate_cleanup_custom(test, rc == 0, res, final,
424 "There are still %d channels in the container\n", rc);
425
426 test_info->res = res;
427 return NULL;
428
429final:
430 iter = CHANNELSTORAGE_API(storage_instance, iterator_all_new);
431 for (; (mock_channel = CHANNELSTORAGE_API(storage_instance, iterator_next, iter));
432 ast_channel_unref(mock_channel)) {
433 ast_test_status_update(test, "%p %s\n", mock_channel, ast_channel_name(mock_channel));
434 i++;
435 }
436 CHANNELSTORAGE_API(storage_instance, iterator_destroy, iter);
437
438 test_info->res = res;
439 return NULL;
440}
441
442static enum ast_test_result_state test_storage(struct ast_test_info *info,
443 enum ast_test_command cmd, struct ast_test *test,
444 const char *storage_name, const char *summary)
445{
446 const struct ast_channelstorage_driver *storage_driver;
447 struct test_info ti = {
448 .test = test,
449 .storage_instance = NULL,
450 .res = AST_TEST_PASS,
451 };
452 pthread_t thread;
453 int rc = 0;
454
455 switch (cmd) {
456 case TEST_INIT:
457 info->name = storage_name;
458 info->category = "/main/channelstorage/";
459 info->summary = summary;
460 info->description = info->summary;
461 return AST_TEST_NOT_RUN;
462 case TEST_EXECUTE:
463 break;
464 }
465
466 storage_driver = ast_channelstorage_get_driver(info->name);
467 if (!storage_driver) {
468 ast_test_status_update(test, "Storage driver %s not registered\n", info->name);
469 return AST_TEST_NOT_RUN;
470 }
471 ti.storage_instance = ast_channelstorage_open(storage_driver, "channels_test");
472 ast_test_validate(test, ti.storage_instance, res);
473
474 rc = ast_pthread_create(&thread, NULL, test_storage_thread, &ti);
475 if (rc) {
476 ast_channelstorage_close(ti.storage_instance);
477 ast_test_status_update(test, "Failed to create thread: %s\n", strerror(rc));
478 return AST_TEST_FAIL;
479 }
480 pthread_join(thread, NULL);
481 ast_channelstorage_close(ti.storage_instance);
482
483 return ti.res;
484}
485
486#define DEFINE_STORAGE_TEST(_name) \
487AST_TEST_DEFINE(_name) \
488{ \
489 return test_storage(info, cmd, test, #_name, "Channel Storage test for " #_name); \
490}
491
492DEFINE_STORAGE_TEST(ao2_legacy)
493
494DEFINE_STORAGE_TEST(cpp_map_name_id)
495
496#define REGISTER_STORAGE_TEST(_name) \
497({ \
498 if (ast_channelstorage_get_driver(#_name)) { \
499 AST_TEST_REGISTER(_name); \
500 } \
501})
502#endif
503
504static void channelstorage_shutdown(void)
505{
506#ifdef TEST_FRAMEWORK
507 /* Unregistering a test that wasn't previously registered is safe */
508 AST_TEST_UNREGISTER(cpp_map_name_id);
509 AST_TEST_UNREGISTER(ao2_legacy);
510#endif
511}
512
514{
515#ifdef TEST_FRAMEWORK
516 /* Tests run in the reverse order registered */
517 REGISTER_STORAGE_TEST(cpp_map_name_id);
518 AST_TEST_REGISTER(ao2_legacy);
519#endif
521
522 return 0;
523}
524
pthread_t thread
Definition: app_sla.c:335
Asterisk main include file. File version handling, generic pbx functions.
int ast_register_cleanup(void(*func)(void))
Register a function to be executed before Asterisk gracefully exits.
Definition: clicompat.c:19
#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
@ CMP_STOP
Definition: astobj2.h:1028
#define ao2_unlock(a)
Definition: astobj2.h:729
#define ao2_lock(a)
Definition: astobj2.h:717
@ OBJ_MULTIPLE
Definition: astobj2.h:1049
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:409
const char * ast_channel_name(const struct ast_channel *chan)
const char * ast_channel_uniqueid(const struct ast_channel *chan)
const char * ast_channel_context(const struct ast_channel *chan)
#define ast_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:3008
#define AST_MAX_UNIQUEID
Definition: channel.h:170
#define AST_MAX_CONTEXT
Definition: channel.h:135
const char * ast_channel_exten(const struct ast_channel *chan)
#define AST_MAX_EXTENSION
Definition: channel.h:134
struct ast_channelstorage_instance * ast_channelstorage_open(const struct ast_channelstorage_driver *storage_driver, const char *instance_name)
int ast_channelstorage_init(void)
int channelstorage_exten_cb(void *obj, void *arg, void *data, int flags)
int channelstorage_name_cb(void *obj, void *arg, void *data, int flags)
int channelstorage_uniqueid_cb(void *obj, void *arg, void *data, int flags)
int ast_channelstorage_register_driver(const struct ast_channelstorage_driver *driver_type)
const struct ast_channelstorage_driver * ast_channelstorage_get_driver(const char *driver_name)
static void channelstorage_shutdown(void)
struct ast_channel * channelstorage_by_name_prefix_or_uniqueid(struct ast_channelstorage_instance *driver, const char *name, size_t name_len)
struct ast_channel * channelstorage_by_name_or_uniqueid(struct ast_channelstorage_instance *driver, const char *name)
void ast_channelstorage_close(struct ast_channelstorage_instance *storage_instance)
struct ast_channel * channelstorage_by_exten(struct ast_channelstorage_instance *driver, const char *exten, const char *context)
static struct @333 storage_drivers
struct ast_channel * channelstorage_by_uniqueid(struct ast_channelstorage_instance *driver, const char *uniqueid)
#define CHANNELSTORAGE_API(_instance, _func,...)
static struct ast_channel * get_by_uniqueid(struct ast_channelstorage_instance *driver, const char *uniqueid)
static struct ast_channelstorage_driver driver_type
static struct ast_channel_iterator * iterator_by_exten_new(struct ast_channelstorage_instance *driver, const char *exten, const char *context)
static struct ast_channel * get_by_name_prefix(struct ast_channelstorage_instance *driver, const char *name, size_t name_len)
static struct ast_channel * iterator_next(struct ast_channelstorage_instance *driver, struct ast_channel_iterator *i)
static int active_channels(struct ast_channelstorage_instance *driver)
returns number of active/allocated channels
static struct ast_channel_iterator * iterator_destroy(struct ast_channelstorage_instance *driver, struct ast_channel_iterator *i)
static struct ast_channel_iterator * iterator_by_name_new(struct ast_channelstorage_instance *driver, const char *name, size_t name_len)
static struct ast_channel * get_by_exten(struct ast_channelstorage_instance *driver, const char *exten, const char *context)
static struct ast_channel_iterator * iterator_all_new(struct ast_channelstorage_instance *driver)
static struct ast_channel * callback(struct ast_channelstorage_instance *driver, ao2_callback_data_fn *cb_fn, void *arg, void *data, int ao2_flags)
static void update(int code_size, int y, int wi, int fi, int dq, int sr, int dqsez, struct g726_state *state_ptr)
Definition: codec_g726.c:367
char * end
Definition: eagi_proxy.c:73
static const char name[]
Definition: format_mp3.c:68
#define LOG_ERROR
#define remove
def info(msg)
Options provided by main asterisk program.
#define NULL
Definition: resample.c:96
#define ast_string_field_init(x, size)
Initialize a field pool and fields.
Definition: stringfields.h:359
#define ast_string_field_build(x, field, fmt, args...)
Set a field to a complex (built) value.
Definition: stringfields.h:555
#define ast_string_field_free_memory(x)
free all memory - to be called before destroying the object
Definition: stringfields.h:374
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
char unique_id[AST_MAX_UNIQUEID]
Main Channel structure associated with a channel.
struct ast_channel_id uniqueid
char exten[AST_MAX_EXTENSION]
const char * data
char context[AST_MAX_CONTEXT]
struct ast_flags flags
struct ast_channelstorage_instance *(* open)(const char *instance_name)
void(* close)(struct ast_channelstorage_instance *driver)
const int argc
Definition: cli.h:160
const char *const * argv
Definition: cli.h:161
Contains all the initialization information required to store a new test definition.
Definition: test.h:235
Test Framework API.
ast_test_command
Definition: test.h:199
@ TEST_INIT
Definition: test.h:200
@ TEST_EXECUTE
Definition: test.h:201
#define AST_TEST_REGISTER(cb)
Definition: test.h:127
#define ast_test_status_update(a, b, c...)
Definition: test.h:129
#define AST_TEST_UNREGISTER(cb)
Definition: test.h:128
ast_test_result_state
Definition: test.h:193
@ AST_TEST_PASS
Definition: test.h:195
@ AST_TEST_FAIL
Definition: test.h:196
@ AST_TEST_NOT_RUN
Definition: test.h:194
int done
Definition: test_amihooks.c:48
int64_t ast_tvdiff_us(struct timeval end, struct timeval start)
Computes the difference (in microseconds) between two struct timeval instances.
Definition: time.h:87
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:159
#define ast_pthread_create(a, b, c, d)
Definition: utils.h:584
long int ast_random(void)
Definition: utils.c:2312
#define AST_VECTOR_SIZE(vec)
Get the number of elements in a vector.
Definition: vector.h:609
#define AST_VECTOR_INIT(vec, size)
Initialize a vector.
Definition: vector.h:113
#define AST_VECTOR_APPEND(vec, elem)
Append an element to a vector, growing the vector if needed.
Definition: vector.h:256
#define AST_VECTOR(name, type)
Define a vector structure.
Definition: vector.h:44
#define AST_VECTOR_GET(vec, idx)
Get an element from a vector.
Definition: vector.h:680