#include "asterisk.h"
#include <regex.h>
#include <ctype.h>
#include "asterisk/module.h"
#include "asterisk/channel.h"
#include "asterisk/pbx.h"
#include "asterisk/utils.h"
#include "asterisk/app.h"
#include "asterisk/indications.h"
#include "asterisk/stringfields.h"
#include "asterisk/global_datastores.h"
Go to the source code of this file.
Defines | |
#define | locked_copy_string(chan, dest, source, len) |
#define | locked_string_field_set(chan, field, source) |
Functions | |
static void | __reg_module (void) |
static void | __unreg_module (void) |
static int | func_channel_read (struct ast_channel *chan, const char *function, char *data, char *buf, size_t len) |
static int | func_channel_write (struct ast_channel *chan, const char *function, char *data, const char *value) |
static int | func_channel_write_real (struct ast_channel *chan, const char *function, char *data, const char *value) |
static int | func_channels_read (struct ast_channel *chan, const char *function, char *data, char *buf, size_t maxlen) |
static int | func_mchan_read (struct ast_channel *chan, const char *function, char *data, struct ast_str **buf, ssize_t len) |
static int | func_mchan_write (struct ast_channel *chan, const char *function, char *data, const char *value) |
static int | load_module (void) |
static int | unload_module (void) |
Variables | |
static struct ast_module_info | __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "Channel information dialplan functions" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "8586c2a7d357cb591cc3a6607a8f62d1" , .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_DEFAULT, } |
static struct ast_module_info * | ast_module_info = &__mod_info |
static struct ast_custom_function | channel_function |
static struct ast_custom_function | channels_function |
static struct ast_custom_function | mchan_function |
static const char *const | transfercapability_table [0x20] |
Ben Winslow
Definition in file func_channel.c.
#define locked_copy_string | ( | chan, | |||
dest, | |||||
source, | |||||
len | ) |
Value:
do { \ ast_channel_lock(chan); \ ast_copy_string(dest, source, len); \ ast_channel_unlock(chan); \ } while (0)
Definition at line 245 of file func_channel.c.
Referenced by func_channel_read().
#define locked_string_field_set | ( | chan, | |||
field, | |||||
source | ) |
Value:
do { \ ast_channel_lock(chan); \ ast_string_field_set(chan, field, source); \ ast_channel_unlock(chan); \ } while (0)
Definition at line 251 of file func_channel.c.
Referenced by func_channel_write_real().
static void __reg_module | ( | void | ) | [static] |
Definition at line 633 of file func_channel.c.
static void __unreg_module | ( | void | ) | [static] |
Definition at line 633 of file func_channel.c.
static int func_channel_read | ( | struct ast_channel * | chan, | |
const char * | function, | |||
char * | data, | |||
char * | buf, | |||
size_t | len | |||
) | [static] |
Definition at line 264 of file func_channel.c.
References ast_channel::_state, ast_channel::accountcode, ast_channel::amaflags, ast_channel::appl, ast_bridged_channel(), ast_channel_datastore_find(), ast_channel_lock, ast_channel_unlock, ast_check_hangup(), ast_copy_string(), AST_FORMAT_AUDIO_MASK, AST_FORMAT_VIDEO_MASK, ast_getformatname(), ast_log(), ast_print_group(), ast_state2str(), ast_strlen_zero(), ast_channel::callgroup, ast_channel::cdr, ast_channel::context, ast_tone_zone::country, ast_datastore::data, ast_channel::data, ast_channel::exten, ast_channel_tech::func_channel_read, ast_channel::hangupsource, ast_channel::language, ast_channel::linkedid, locked_copy_string, LOG_WARNING, ast_secure_call_store::media, ast_channel::musicclass, ast_channel::name, ast_channel::nativeformats, ast_channel::parkinglot, pbx_builtin_getvar_helper(), ast_channel::peeraccount, ast_channel::readformat, secure_call_info, ast_secure_call_store::signaling, ast_channel::tech, ast_channel::transfercapability, ast_channel_tech::type, ast_channel::uniqueid, ast_channel::userfield, ast_channel::writeformat, and ast_channel::zone.
00266 { 00267 int ret = 0; 00268 00269 if (!strcasecmp(data, "audionativeformat")) 00270 /* use the _multiple version when chan->nativeformats holds multiple formats */ 00271 /* ast_getformatname_multiple(buf, len, chan->nativeformats & AST_FORMAT_AUDIO_MASK); */ 00272 ast_copy_string(buf, ast_getformatname(chan->nativeformats & AST_FORMAT_AUDIO_MASK), len); 00273 else if (!strcasecmp(data, "videonativeformat")) 00274 /* use the _multiple version when chan->nativeformats holds multiple formats */ 00275 /* ast_getformatname_multiple(buf, len, chan->nativeformats & AST_FORMAT_VIDEO_MASK); */ 00276 ast_copy_string(buf, ast_getformatname(chan->nativeformats & AST_FORMAT_VIDEO_MASK), len); 00277 else if (!strcasecmp(data, "audioreadformat")) 00278 ast_copy_string(buf, ast_getformatname(chan->readformat), len); 00279 else if (!strcasecmp(data, "audiowriteformat")) 00280 ast_copy_string(buf, ast_getformatname(chan->writeformat), len); 00281 #ifdef CHANNEL_TRACE 00282 else if (!strcasecmp(data, "trace")) { 00283 ast_channel_lock(chan); 00284 ast_copy_string(buf, ast_channel_trace_is_enabled(chan) ? "1" : "0", len); 00285 ast_channel_unlock(chan); 00286 } 00287 #endif 00288 else if (!strcasecmp(data, "tonezone") && chan->zone) 00289 locked_copy_string(chan, buf, chan->zone->country, len); 00290 else if (!strcasecmp(data, "language")) 00291 locked_copy_string(chan, buf, chan->language, len); 00292 else if (!strcasecmp(data, "musicclass")) 00293 locked_copy_string(chan, buf, chan->musicclass, len); 00294 else if (!strcasecmp(data, "name")) { 00295 locked_copy_string(chan, buf, chan->name, len); 00296 } else if (!strcasecmp(data, "parkinglot")) 00297 locked_copy_string(chan, buf, chan->parkinglot, len); 00298 else if (!strcasecmp(data, "state")) 00299 locked_copy_string(chan, buf, ast_state2str(chan->_state), len); 00300 else if (!strcasecmp(data, "channeltype")) 00301 locked_copy_string(chan, buf, chan->tech->type, len); 00302 else if (!strcasecmp(data, "accountcode")) 00303 locked_copy_string(chan, buf, chan->accountcode, len); 00304 else if (!strcasecmp(data, "checkhangup")) { 00305 ast_channel_lock(chan); 00306 ast_copy_string(buf, ast_check_hangup(chan) ? "1" : "0", len); 00307 ast_channel_unlock(chan); 00308 } else if (!strcasecmp(data, "peeraccount")) 00309 locked_copy_string(chan, buf, chan->peeraccount, len); 00310 else if (!strcasecmp(data, "hangupsource")) 00311 locked_copy_string(chan, buf, chan->hangupsource, len); 00312 else if (!strcasecmp(data, "appname") && chan->appl) 00313 locked_copy_string(chan, buf, chan->appl, len); 00314 else if (!strcasecmp(data, "appdata") && chan->data) 00315 locked_copy_string(chan, buf, chan->data, len); 00316 else if (!strcasecmp(data, "exten") && chan->data) 00317 locked_copy_string(chan, buf, chan->exten, len); 00318 else if (!strcasecmp(data, "context") && chan->data) 00319 locked_copy_string(chan, buf, chan->context, len); 00320 else if (!strcasecmp(data, "userfield") && chan->data) 00321 locked_copy_string(chan, buf, chan->userfield, len); 00322 else if (!strcasecmp(data, "channame") && chan->data) 00323 locked_copy_string(chan, buf, chan->name, len); 00324 else if (!strcasecmp(data, "linkedid")) { 00325 ast_channel_lock(chan); 00326 if (ast_strlen_zero(chan->linkedid)) { 00327 /* fall back on the channel's uniqueid if linkedid is unset */ 00328 ast_copy_string(buf, chan->uniqueid, len); 00329 } 00330 else { 00331 ast_copy_string(buf, chan->linkedid, len); 00332 } 00333 ast_channel_unlock(chan); 00334 } else if (!strcasecmp(data, "peer")) { 00335 struct ast_channel *p; 00336 ast_channel_lock(chan); 00337 p = ast_bridged_channel(chan); 00338 if (p || chan->tech || chan->cdr) /* dummy channel? if so, we hid the peer name in the language */ 00339 ast_copy_string(buf, (p ? p->name : ""), len); 00340 else { 00341 /* a dummy channel can still pass along bridged peer info via 00342 the BRIDGEPEER variable */ 00343 const char *pname = pbx_builtin_getvar_helper(chan, "BRIDGEPEER"); 00344 if (!ast_strlen_zero(pname)) 00345 ast_copy_string(buf, pname, len); /* a horrible kludge, but... how else? */ 00346 else 00347 buf[0] = 0; 00348 } 00349 ast_channel_unlock(chan); 00350 } else if (!strcasecmp(data, "uniqueid")) { 00351 locked_copy_string(chan, buf, chan->uniqueid, len); 00352 } else if (!strcasecmp(data, "transfercapability")) 00353 locked_copy_string(chan, buf, transfercapability_table[chan->transfercapability & 0x1f], len); 00354 else if (!strcasecmp(data, "callgroup")) { 00355 char groupbuf[256]; 00356 locked_copy_string(chan, buf, ast_print_group(groupbuf, sizeof(groupbuf), chan->callgroup), len); 00357 } else if (!strcasecmp(data, "amaflags")) { 00358 char amabuf[256]; 00359 snprintf(amabuf,sizeof(amabuf), "%d", chan->amaflags); 00360 locked_copy_string(chan, buf, amabuf, len); 00361 } else if (!strncasecmp(data, "secure_bridge_", 14)) { 00362 struct ast_datastore *ds; 00363 ast_channel_lock(chan); 00364 if ((ds = ast_channel_datastore_find(chan, &secure_call_info, NULL))) { 00365 struct ast_secure_call_store *encrypt = ds->data; 00366 if (!strcasecmp(data, "secure_bridge_signaling")) { 00367 snprintf(buf, len, "%s", encrypt->signaling ? "1" : ""); 00368 } else if (!strcasecmp(data, "secure_bridge_media")) { 00369 snprintf(buf, len, "%s", encrypt->media ? "1" : ""); 00370 } 00371 } 00372 ast_channel_unlock(chan); 00373 } else if (!chan->tech || !chan->tech->func_channel_read || chan->tech->func_channel_read(chan, function, data, buf, len)) { 00374 ast_log(LOG_WARNING, "Unknown or unavailable item requested: '%s'\n", data); 00375 ret = -1; 00376 } 00377 00378 return ret; 00379 }
static int func_channel_write | ( | struct ast_channel * | chan, | |
const char * | function, | |||
char * | data, | |||
const char * | value | |||
) | [static] |
Definition at line 499 of file func_channel.c.
References AST_CHAN_WRITE_INFO_T_VERSION, ast_channel_setoption(), AST_OPTION_CHANNEL_WRITE, ast_channel::data, and func_channel_write_real().
00500 { 00501 int res; 00502 ast_chan_write_info_t write_info = { 00503 .version = AST_CHAN_WRITE_INFO_T_VERSION, 00504 .write_fn = func_channel_write_real, 00505 .chan = chan, 00506 .function = function, 00507 .data = data, 00508 .value = value, 00509 }; 00510 00511 res = func_channel_write_real(chan, function, data, value); 00512 ast_channel_setoption(chan, AST_OPTION_CHANNEL_WRITE, &write_info, sizeof(write_info), 0); 00513 00514 return res; 00515 }
static int func_channel_write_real | ( | struct ast_channel * | chan, | |
const char * | function, | |||
char * | data, | |||
const char * | value | |||
) | [static] |
Definition at line 381 of file func_channel.c.
References accountcode, ast_channel::amaflags, ast_calloc, ast_channel_datastore_add(), ast_channel_datastore_find(), ast_channel_lock, ast_channel_setoption(), ast_channel_unlock, ast_datastore_alloc, ast_false(), ast_free, ast_get_group(), ast_get_indication_zone(), ast_log(), AST_OPTION_RXGAIN, AST_OPTION_TXGAIN, ast_set_hangupsource(), ast_tone_zone_ref(), ast_tone_zone_unref(), ast_true(), ast_channel::callgroup, ast_channel_tech::func_channel_write, language, locked_string_field_set, LOG_ERROR, LOG_WARNING, ast_secure_call_store::media, musicclass, parkinglot, secure_call_info, ast_secure_call_store::signaling, ast_channel::tech, ast_channel::transfercapability, and ast_channel::zone.
Referenced by func_channel_write().
00383 { 00384 int ret = 0; 00385 signed char gainset; 00386 00387 if (!strcasecmp(data, "language")) 00388 locked_string_field_set(chan, language, value); 00389 else if (!strcasecmp(data, "parkinglot")) 00390 locked_string_field_set(chan, parkinglot, value); 00391 else if (!strcasecmp(data, "musicclass")) 00392 locked_string_field_set(chan, musicclass, value); 00393 else if (!strcasecmp(data, "accountcode")) 00394 locked_string_field_set(chan, accountcode, value); 00395 else if (!strcasecmp(data, "userfield")) 00396 locked_string_field_set(chan, userfield, value); 00397 else if (!strcasecmp(data, "amaflags")) { 00398 ast_channel_lock(chan); 00399 if(isdigit(*value)) { 00400 sscanf(value, "%30d", &chan->amaflags); 00401 } else if (!strcasecmp(value,"OMIT")){ 00402 chan->amaflags = 1; 00403 } else if (!strcasecmp(value,"BILLING")){ 00404 chan->amaflags = 2; 00405 } else if (!strcasecmp(value,"DOCUMENTATION")){ 00406 chan->amaflags = 3; 00407 } 00408 ast_channel_unlock(chan); 00409 } else if (!strcasecmp(data, "peeraccount")) 00410 locked_string_field_set(chan, peeraccount, value); 00411 else if (!strcasecmp(data, "hangupsource")) 00412 /* XXX - should we be forcing this here? */ 00413 ast_set_hangupsource(chan, value, 0); 00414 #ifdef CHANNEL_TRACE 00415 else if (!strcasecmp(data, "trace")) { 00416 ast_channel_lock(chan); 00417 if (ast_true(value)) 00418 ret = ast_channel_trace_enable(chan); 00419 else if (ast_false(value)) 00420 ret = ast_channel_trace_disable(chan); 00421 else { 00422 ret = -1; 00423 ast_log(LOG_WARNING, "Invalid value for CHANNEL(trace)."); 00424 } 00425 ast_channel_unlock(chan); 00426 } 00427 #endif 00428 else if (!strcasecmp(data, "tonezone")) { 00429 struct ast_tone_zone *new_zone; 00430 if (!(new_zone = ast_get_indication_zone(value))) { 00431 ast_log(LOG_ERROR, "Unknown country code '%s' for tonezone. Check indications.conf for available country codes.\n", value); 00432 ret = -1; 00433 } else { 00434 ast_channel_lock(chan); 00435 if (chan->zone) { 00436 chan->zone = ast_tone_zone_unref(chan->zone); 00437 } 00438 chan->zone = ast_tone_zone_ref(new_zone); 00439 ast_channel_unlock(chan); 00440 new_zone = ast_tone_zone_unref(new_zone); 00441 } 00442 } else if (!strcasecmp(data, "callgroup")) 00443 chan->callgroup = ast_get_group(value); 00444 else if (!strcasecmp(data, "txgain")) { 00445 sscanf(value, "%4hhd", &gainset); 00446 ast_channel_setoption(chan, AST_OPTION_TXGAIN, &gainset, sizeof(gainset), 0); 00447 } else if (!strcasecmp(data, "rxgain")) { 00448 sscanf(value, "%4hhd", &gainset); 00449 ast_channel_setoption(chan, AST_OPTION_RXGAIN, &gainset, sizeof(gainset), 0); 00450 } else if (!strcasecmp(data, "transfercapability")) { 00451 unsigned short i; 00452 for (i = 0; i < 0x20; i++) { 00453 if (!strcasecmp(transfercapability_table[i], value) && strcmp(value, "UNK")) { 00454 chan->transfercapability = i; 00455 break; 00456 } 00457 } 00458 } else if (!strncasecmp(data, "secure_bridge_", 14)) { 00459 struct ast_datastore *ds; 00460 struct ast_secure_call_store *store; 00461 00462 if (!chan || !value) { 00463 return -1; 00464 } 00465 00466 ast_channel_lock(chan); 00467 if (!(ds = ast_channel_datastore_find(chan, &secure_call_info, NULL))) { 00468 if (!(ds = ast_datastore_alloc(&secure_call_info, NULL))) { 00469 ast_channel_unlock(chan); 00470 return -1; 00471 } 00472 if (!(store = ast_calloc(1, sizeof(*store)))) { 00473 ast_channel_unlock(chan); 00474 ast_free(ds); 00475 return -1; 00476 } 00477 ds->data = store; 00478 ast_channel_datastore_add(chan, ds); 00479 } else { 00480 store = ds->data; 00481 } 00482 ast_channel_unlock(chan); 00483 00484 if (!strcasecmp(data, "secure_bridge_signaling")) { 00485 store->signaling = ast_true(value) ? 1 : 0; 00486 } else if (!strcasecmp(data, "secure_bridge_media")) { 00487 store->media = ast_true(value) ? 1 : 0; 00488 } 00489 } else if (!chan->tech->func_channel_write 00490 || chan->tech->func_channel_write(chan, function, data, value)) { 00491 ast_log(LOG_WARNING, "Unknown or unavailable item requested: '%s'\n", 00492 data); 00493 ret = -1; 00494 } 00495 00496 return ret; 00497 }
static int func_channels_read | ( | struct ast_channel * | chan, | |
const char * | function, | |||
char * | data, | |||
char * | buf, | |||
size_t | maxlen | |||
) | [static] |
Definition at line 523 of file func_channel.c.
References ast_channel_iterator_all_new(), ast_channel_iterator_destroy(), ast_channel_iterator_next(), ast_channel_lock, ast_channel_unlock, ast_channel_unref, ast_log(), ast_strlen_zero(), and LOG_WARNING.
00524 { 00525 struct ast_channel *c = NULL; 00526 regex_t re; 00527 int res; 00528 size_t buflen = 0; 00529 struct ast_channel_iterator *iter; 00530 00531 buf[0] = '\0'; 00532 00533 if (!ast_strlen_zero(data)) { 00534 if ((res = regcomp(&re, data, REG_EXTENDED | REG_ICASE | REG_NOSUB))) { 00535 regerror(res, &re, buf, maxlen); 00536 ast_log(LOG_WARNING, "Error compiling regular expression for %s(%s): %s\n", function, data, buf); 00537 return -1; 00538 } 00539 } 00540 00541 if (!(iter = ast_channel_iterator_all_new())) { 00542 if (!ast_strlen_zero(data)) { 00543 regfree(&re); 00544 } 00545 return -1; 00546 } 00547 00548 while ((c = ast_channel_iterator_next(iter))) { 00549 ast_channel_lock(c); 00550 if (ast_strlen_zero(data) || regexec(&re, c->name, 0, NULL, 0) == 0) { 00551 size_t namelen = strlen(c->name); 00552 if (buflen + namelen + (ast_strlen_zero(buf) ? 0 : 1) + 1 < maxlen) { 00553 if (!ast_strlen_zero(buf)) { 00554 strcat(buf, " "); 00555 buflen++; 00556 } 00557 strcat(buf, c->name); 00558 buflen += namelen; 00559 } else { 00560 ast_log(LOG_WARNING, "Number of channels exceeds the available buffer space. Output will be truncated!\n"); 00561 } 00562 } 00563 ast_channel_unlock(c); 00564 c = ast_channel_unref(c); 00565 } 00566 00567 ast_channel_iterator_destroy(iter); 00568 00569 if (!ast_strlen_zero(data)) { 00570 regfree(&re); 00571 } 00572 00573 return 0; 00574 }
static int func_mchan_read | ( | struct ast_channel * | chan, | |
const char * | function, | |||
char * | data, | |||
struct ast_str ** | buf, | |||
ssize_t | len | |||
) | [static] |
Definition at line 581 of file func_channel.c.
References ast_channel_get_by_name(), ast_channel_unref, ast_str_substitute_variables(), and ast_channel::linkedid.
00583 { 00584 struct ast_channel *mchan = ast_channel_get_by_name(chan->linkedid); 00585 char *template = alloca(4 + strlen(data)); 00586 sprintf(template, "${%s}", data); /* SAFE */ 00587 ast_str_substitute_variables(buf, len, mchan ? mchan : chan, template); 00588 if (mchan) { 00589 ast_channel_unref(mchan); 00590 } 00591 return 0; 00592 }
static int func_mchan_write | ( | struct ast_channel * | chan, | |
const char * | function, | |||
char * | data, | |||
const char * | value | |||
) | [static] |
Definition at line 594 of file func_channel.c.
References ast_channel_get_by_name(), ast_channel_unref, ast_channel::linkedid, and pbx_builtin_setvar_helper().
00596 { 00597 struct ast_channel *mchan = ast_channel_get_by_name(chan->linkedid); 00598 pbx_builtin_setvar_helper(mchan ? mchan : chan, data, value); 00599 if (mchan) { 00600 ast_channel_unref(mchan); 00601 } 00602 return 0; 00603 }
static int load_module | ( | void | ) | [static] |
Definition at line 622 of file func_channel.c.
References ast_custom_function_register, channel_function, channels_function, and mchan_function.
00623 { 00624 int res = 0; 00625 00626 res |= ast_custom_function_register(&channel_function); 00627 res |= ast_custom_function_register(&channels_function); 00628 res |= ast_custom_function_register(&mchan_function); 00629 00630 return res; 00631 }
static int unload_module | ( | void | ) | [static] |
Definition at line 611 of file func_channel.c.
References ast_custom_function_unregister(), channel_function, channels_function, and mchan_function.
00612 { 00613 int res = 0; 00614 00615 res |= ast_custom_function_unregister(&channel_function); 00616 res |= ast_custom_function_unregister(&channels_function); 00617 res |= ast_custom_function_unregister(&mchan_function); 00618 00619 return res; 00620 }
struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "Channel information dialplan functions" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "8586c2a7d357cb591cc3a6607a8f62d1" , .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_DEFAULT, } [static] |
Definition at line 633 of file func_channel.c.
struct ast_module_info* ast_module_info = &__mod_info [static] |
Definition at line 633 of file func_channel.c.
struct ast_custom_function channel_function [static] |
Initial value:
{ .name = "CHANNEL", .read = func_channel_read, .write = func_channel_write, }
Definition at line 517 of file func_channel.c.
Referenced by load_module(), and unload_module().
struct ast_custom_function channels_function [static] |
Initial value:
{ .name = "CHANNELS", .read = func_channels_read, }
Definition at line 576 of file func_channel.c.
Referenced by load_module(), and unload_module().
struct ast_custom_function mchan_function [static] |
Initial value:
{ .name = "MASTER_CHANNEL", .read2 = func_mchan_read, .write = func_mchan_write, }
Definition at line 605 of file func_channel.c.
Referenced by load_module(), and unload_module().
const char* const transfercapability_table[0x20] [static] |
Initial value:
{ "SPEECH", "UNK", "UNK", "UNK", "UNK", "UNK", "UNK", "UNK", "DIGITAL", "RESTRICTED_DIGITAL", "UNK", "UNK", "UNK", "UNK", "UNK", "UNK", "3K1AUDIO", "DIGITAL_W_TONES", "UNK", "UNK", "UNK", "UNK", "UNK", "UNK", "VIDEO", "UNK", "UNK", "UNK", "UNK", "UNK", "UNK", "UNK", }
Definition at line 258 of file func_channel.c.