00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
#include <asterisk/lock.h>
00015
#include <asterisk/frame.h>
00016
#include <asterisk/logger.h>
00017
#include <asterisk/options.h>
00018
#include <asterisk/cli.h>
00019
#include <asterisk/term.h>
00020
#include <asterisk/utils.h>
00021
#include <stdlib.h>
00022
#include <unistd.h>
00023
#include <string.h>
00024
#include <errno.h>
00025
#include <pthread.h>
00026
#include <stdio.h>
00027
#include "asterisk.h"
00028
00029
#ifdef TRACE_FRAMES
00030
static int headers = 0;
00031
static struct ast_frame *headerlist = NULL;
00032
AST_MUTEX_DEFINE_STATIC(framelock);
00033
#endif
00034
00035 #define SMOOTHER_SIZE 8000
00036
00037 struct ast_smoother {
00038 int size;
00039 int format;
00040 int readdata;
00041 int optimizablestream;
00042 int flags;
00043 float samplesperbyte;
00044 struct ast_frame f;
00045 struct timeval delivery;
00046 char data[
SMOOTHER_SIZE];
00047 char framedata[
SMOOTHER_SIZE +
AST_FRIENDLY_OFFSET];
00048 struct ast_frame *
opt;
00049 int len;
00050 };
00051
00052 void ast_smoother_reset(
struct ast_smoother *s,
int size)
00053 {
00054 memset(
s, 0,
sizeof(
struct ast_smoother));
00055
s->size = size;
00056 }
00057
00058 struct ast_smoother *
ast_smoother_new(
int size)
00059 {
00060
struct ast_smoother *
s;
00061
if (size < 1)
00062
return NULL;
00063
s =
malloc(
sizeof(
struct ast_smoother));
00064
if (
s)
00065
ast_smoother_reset(
s, size);
00066
return s;
00067 }
00068
00069 int ast_smoother_get_flags(
struct ast_smoother *s)
00070 {
00071
return s->flags;
00072 }
00073
00074 void ast_smoother_set_flags(
struct ast_smoother *s,
int flags)
00075 {
00076
s->flags = flags;
00077 }
00078
00079 int ast_smoother_feed(
struct ast_smoother *s,
struct ast_frame *f)
00080 {
00081
if (f->
frametype !=
AST_FRAME_VOICE) {
00082
ast_log(
LOG_WARNING,
"Huh? Can't smooth a non-voice frame!\n");
00083
return -1;
00084 }
00085
if (!
s->format) {
00086
s->format = f->
subclass;
00087
s->samplesperbyte = (
float)f->
samples / (
float)f->
datalen;
00088 }
else if (
s->format != f->
subclass) {
00089
ast_log(
LOG_WARNING,
"Smoother was working on %d format frames, now trying to feed %d?\n",
s->format, f->
subclass);
00090
return -1;
00091 }
00092
if (
s->len + f->
datalen >
SMOOTHER_SIZE) {
00093
ast_log(
LOG_WARNING,
"Out of smoother space\n");
00094
return -1;
00095 }
00096
if (((f->
datalen ==
s->size) || ((f->
datalen < 10) && (
s->flags &
AST_SMOOTHER_FLAG_G729)))
00097 && !
s->opt && (f->
offset >=
AST_MIN_OFFSET)) {
00098
if (!
s->len) {
00099
00100
00101
00102
s->opt = f;
00103
return 0;
00104 }
else {
00105
s->optimizablestream++;
00106
if (
s->optimizablestream > 10) {
00107
00108
00109
00110
00111
00112
s->len = 0;
00113
s->opt = f;
00114
return 0;
00115 }
00116 }
00117 }
else
00118
s->optimizablestream = 0;
00119
if (
s->flags &
AST_SMOOTHER_FLAG_G729) {
00120
if (
s->len % 10) {
00121
ast_log(
LOG_NOTICE,
"Dropping extra frame of G.729 since we already have a VAD frame at the end\n");
00122
return 0;
00123 }
00124 }
00125 memcpy(
s->data +
s->len, f->
data, f->
datalen);
00126
00127
if (!
s->len || (!f->
delivery.tv_sec && !f->
delivery.tv_usec) ||
00128 (!
s->delivery.tv_sec && !
s->delivery.tv_usec))
00129
s->delivery = f->
delivery;
00130
s->len += f->
datalen;
00131
return 0;
00132 }
00133
00134 struct ast_frame *
ast_smoother_read(
struct ast_smoother *s)
00135 {
00136
struct ast_frame *opt;
00137
int len;
00138
00139
if (
s->opt) {
00140 opt =
s->opt;
00141
s->opt = NULL;
00142
return opt;
00143 }
00144
00145
00146
if (
s->len <
s->size) {
00147
00148
if (!((
s->flags &
AST_SMOOTHER_FLAG_G729) && (
s->size % 10)))
00149
return NULL;
00150 }
00151 len =
s->size;
00152
if (len >
s->len)
00153 len =
s->len;
00154
00155
s->f.frametype =
AST_FRAME_VOICE;
00156
s->f.subclass =
s->format;
00157
s->f.data =
s->framedata +
AST_FRIENDLY_OFFSET;
00158
s->f.offset =
AST_FRIENDLY_OFFSET;
00159
s->f.datalen = len;
00160
00161
s->f.samples = len *
s->samplesperbyte;
00162
s->f.delivery =
s->delivery;
00163
00164 memcpy(
s->f.data,
s->data, len);
00165
s->len -= len;
00166
00167
if (
s->len) {
00168
00169
00170 memmove(
s->data,
s->data + len,
s->len);
00171
if (
s->delivery.tv_sec ||
s->delivery.tv_usec) {
00172
00173
s->delivery.tv_sec += (len *
s->samplesperbyte) / 8000.0;
00174
s->delivery.tv_usec += (((
int)(len *
s->samplesperbyte)) % 8000) * 125;
00175
if (
s->delivery.tv_usec > 1000000) {
00176
s->delivery.tv_usec -= 1000000;
00177
s->delivery.tv_sec += 1;
00178 }
00179 }
00180 }
00181
00182
return &
s->f;
00183 }
00184
00185 void ast_smoother_free(
struct ast_smoother *s)
00186 {
00187
free(
s);
00188 }
00189
00190
static struct ast_frame *ast_frame_header_new(
void)
00191 {
00192
struct ast_frame *f;
00193 f =
malloc(
sizeof(
struct ast_frame));
00194
if (f)
00195 memset(f, 0,
sizeof(
struct ast_frame));
00196
#ifdef TRACE_FRAMES
00197
if (f) {
00198 headers++;
00199 f->prev = NULL;
00200
ast_mutex_lock(&framelock);
00201 f->next = headerlist;
00202
if (headerlist)
00203 headerlist->prev = f;
00204 headerlist = f;
00205
ast_mutex_unlock(&framelock);
00206 }
00207
#endif
00208
return f;
00209 }
00210
00211
00212
00213
00214
00215
00216 void ast_frfree(
struct ast_frame *fr)
00217 {
00218
if (fr->
mallocd &
AST_MALLOCD_DATA) {
00219
if (fr->
data)
00220
free(fr->
data - fr->
offset);
00221 }
00222
if (fr->
mallocd &
AST_MALLOCD_SRC) {
00223
if (fr->
src)
00224
free(fr->
src);
00225 }
00226
if (fr->
mallocd &
AST_MALLOCD_HDR) {
00227
#ifdef TRACE_FRAMES
00228
headers--;
00229
ast_mutex_lock(&framelock);
00230
if (fr->
next)
00231 fr->
next->
prev = fr->
prev;
00232
if (fr->
prev)
00233 fr->
prev->
next = fr->
next;
00234
else
00235 headerlist = fr->
next;
00236
ast_mutex_unlock(&framelock);
00237
#endif
00238
free(fr);
00239 }
00240 }
00241
00242 struct ast_frame *
ast_frisolate(
struct ast_frame *fr)
00243 {
00244
struct ast_frame *out;
00245
if (!(fr->
mallocd &
AST_MALLOCD_HDR)) {
00246
00247 out = ast_frame_header_new();
00248
if (!out) {
00249
ast_log(
LOG_WARNING,
"Out of memory\n");
00250
return NULL;
00251 }
00252 out->frametype = fr->
frametype;
00253 out->subclass = fr->
subclass;
00254 out->datalen = 0;
00255 out->samples = fr->
samples;
00256 out->offset = 0;
00257 out->src = NULL;
00258 out->data = NULL;
00259 }
else {
00260 out = fr;
00261 }
00262
if (!(fr->
mallocd &
AST_MALLOCD_SRC)) {
00263
if (fr->
src)
00264 out->
src =
strdup(fr->
src);
00265 }
else
00266 out->src = fr->
src;
00267
if (!(fr->
mallocd &
AST_MALLOCD_DATA)) {
00268 out->data =
malloc(fr->
datalen +
AST_FRIENDLY_OFFSET);
00269
if (!out->data) {
00270
free(out);
00271
ast_log(
LOG_WARNING,
"Out of memory\n");
00272
return NULL;
00273 }
00274 out->data +=
AST_FRIENDLY_OFFSET;
00275 out->offset =
AST_FRIENDLY_OFFSET;
00276 out->datalen = fr->
datalen;
00277 memcpy(out->data, fr->
data, fr->
datalen);
00278 }
00279 out->mallocd =
AST_MALLOCD_HDR |
AST_MALLOCD_SRC |
AST_MALLOCD_DATA;
00280
return out;
00281 }
00282
00283 struct ast_frame *
ast_frdup(
struct ast_frame *f)
00284 {
00285
struct ast_frame *out;
00286
int len, srclen = 0;
00287
void *buf;
00288
00289 len =
sizeof(
struct ast_frame) +
AST_FRIENDLY_OFFSET + f->datalen;
00290
00291
if (f->
src)
00292 srclen = strlen(f->
src);
00293
if (srclen > 0)
00294 len += srclen + 1;
00295 buf =
malloc(len);
00296
if (!buf)
00297
return NULL;
00298 out = buf;
00299
00300
00301 out->frametype = f->
frametype;
00302 out->subclass = f->
subclass;
00303 out->datalen = f->
datalen;
00304 out->samples = f->
samples;
00305 out->delivery = f->
delivery;
00306 out->mallocd =
AST_MALLOCD_HDR;
00307 out->offset =
AST_FRIENDLY_OFFSET;
00308 out->data = buf +
sizeof(
struct ast_frame) +
AST_FRIENDLY_OFFSET;
00309
if (srclen > 0) {
00310 out->src = out->data + f->
datalen;
00311
00312 strcpy(out->src, f->
src);
00313 }
else
00314 out->src = NULL;
00315 out->prev = NULL;
00316 out->next = NULL;
00317 memcpy(out->data, f->
data, out->datalen);
00318
return out;
00319 }
00320
00321 struct ast_frame *
ast_fr_fdread(
int fd)
00322 {
00323
char buf[65536];
00324
int res;
00325
int ttl =
sizeof(
struct ast_frame);
00326
struct ast_frame *f = (
struct ast_frame *)buf;
00327
00328
00329
00330
while(ttl) {
00331 res = read(fd, buf, ttl);
00332
if (res < 0) {
00333
ast_log(
LOG_WARNING,
"Bad read on %d: %s\n", fd, strerror(errno));
00334
return NULL;
00335 }
00336 ttl -= res;
00337 }
00338
00339
00340 f->mallocd = 0;
00341
00342 f->data = buf +
sizeof(
struct ast_frame);
00343 f->offset = 0;
00344
00345 f->mallocd = 0;
00346
00347 f->src = __FUNCTION__;
00348
if (f->datalen >
sizeof(buf) -
sizeof(
struct ast_frame)) {
00349
00350
ast_log(
LOG_WARNING,
"Strange read (%d bytes)\n", f->datalen);
00351
return NULL;
00352 }
00353
if (f->datalen) {
00354
if ((res = read(fd, f->data, f->datalen)) != f->datalen) {
00355
00356
ast_log(
LOG_WARNING,
"How very strange, expected %d, got %d\n", f->datalen, res);
00357
return NULL;
00358 }
00359 }
00360
if ((f->frametype ==
AST_FRAME_CONTROL) && (f->subclass ==
AST_CONTROL_HANGUP)) {
00361
return NULL;
00362 }
00363
return ast_frisolate(f);
00364 }
00365
00366
00367
00368
00369 int ast_fr_fdwrite(
int fd,
struct ast_frame *frame)
00370 {
00371
00372
if (write(fd, frame,
sizeof(
struct ast_frame)) !=
sizeof(
struct ast_frame)) {
00373
ast_log(
LOG_WARNING,
"Write error: %s\n", strerror(errno));
00374
return -1;
00375 }
00376
if (write(fd, frame->
data, frame->
datalen) != frame->
datalen) {
00377
ast_log(
LOG_WARNING,
"Write error: %s\n", strerror(errno));
00378
return -1;
00379 }
00380
return 0;
00381 }
00382
00383 int ast_fr_fdhangup(
int fd)
00384 {
00385
struct ast_frame hangup = {
00386
AST_FRAME_CONTROL,
00387
AST_CONTROL_HANGUP
00388 };
00389
return ast_fr_fdwrite(fd, &hangup);
00390 }
00391
00392 char*
ast_getformatname(
int format)
00393 {
00394
if (format ==
AST_FORMAT_G723_1)
00395
return "G723";
00396
else if (format ==
AST_FORMAT_GSM)
00397
return "GSM";
00398
else if (format ==
AST_FORMAT_ULAW)
00399
return "ULAW";
00400
else if (format ==
AST_FORMAT_ALAW)
00401
return "ALAW";
00402
else if (format ==
AST_FORMAT_G726)
00403
return "G726";
00404
else if (format ==
AST_FORMAT_SLINEAR)
00405
return "SLINR";
00406
else if (format ==
AST_FORMAT_LPC10)
00407
return "LPC10";
00408
else if (format ==
AST_FORMAT_ADPCM)
00409
return "ADPCM";
00410
else if (format ==
AST_FORMAT_G729A)
00411
return "G729A";
00412
else if (format ==
AST_FORMAT_SPEEX)
00413
return "SPEEX";
00414
else if (format ==
AST_FORMAT_ILBC)
00415
return "ILBC";
00416
else if (format ==
AST_FORMAT_JPEG)
00417
return "JPEG";
00418
else if (format ==
AST_FORMAT_PNG)
00419
return "PNG";
00420
else if (format ==
AST_FORMAT_H261)
00421
return "H261";
00422
else if (format ==
AST_FORMAT_H263)
00423
return "H263";
00424
return "UNKN";
00425 }
00426
00427 char*
ast_getformatname_multiple(
char *buf,
unsigned n,
int format) {
00428
unsigned u=1;
00429
unsigned len;
00430
char *b = buf;
00431
char *start = buf;
00432
if (!n)
return buf;
00433 snprintf(b,n,
"0x%x(",format);
00434 len = strlen(b);
00435 b += len;
00436 n -= len;
00437 start = b;
00438
while (u) {
00439
if (u&format) {
00440 snprintf(b,n,
"%s|",
ast_getformatname(u));
00441 len = strlen(b);
00442 b += len;
00443 n -= len;
00444 }
00445 u *= 2;
00446 }
00447
if (start==b)
00448 snprintf(start,n,
"EMPTY)");
00449
else if (n>1)
00450 b[-1]=
')';
00451
return buf;
00452 }
00453
00454 int ast_getformatbyname(
char *name)
00455 {
00456
if (!strcasecmp(name,
"g723.1"))
00457
return AST_FORMAT_G723_1;
00458
else if (!strcasecmp(name,
"gsm"))
00459
return AST_FORMAT_GSM;
00460
else if (!strcasecmp(name,
"ulaw"))
00461
return AST_FORMAT_ULAW;
00462
else if (!strcasecmp(name,
"alaw"))
00463
return AST_FORMAT_ALAW;
00464
else if (!strcasecmp(name,
"g726"))
00465
return AST_FORMAT_G726;
00466
else if (!strcasecmp(name,
"slinear"))
00467
return AST_FORMAT_SLINEAR;
00468
else if (!strcasecmp(name,
"lpc10"))
00469
return AST_FORMAT_LPC10;
00470
else if (!strcasecmp(name,
"adpcm"))
00471
return AST_FORMAT_ADPCM;
00472
else if (!strcasecmp(name,
"g729"))
00473
return AST_FORMAT_G729A;
00474
else if (!strcasecmp(name,
"speex"))
00475
return AST_FORMAT_SPEEX;
00476
else if (!strcasecmp(name,
"ilbc"))
00477
return AST_FORMAT_ILBC;
00478
else if (!strcasecmp(name,
"h261"))
00479
return AST_FORMAT_H261;
00480
else if (!strcasecmp(name,
"h263"))
00481
return AST_FORMAT_H263;
00482
else if (!strcasecmp(name,
"all"))
00483
return 0x7FFFFFFF;
00484
return 0;
00485 }
00486
00487 char *
ast_codec2str(
int codec) {
00488
static char codecs[25][30] = {
00489
00490
"G.723.1",
00491
"GSM",
00492
"G.711 u-law",
00493
"G.711 A-law",
00494
"G.726",
00495
"ADPCM",
00496
"16 bit Signed Linear PCM",
00497
"LPC10",
00498
"G.729A audio",
00499
"SpeeX",
00500
"iLBC",
00501
"undefined",
00502
"undefined",
00503
"undefined",
00504
"undefined",
00505
"Maximum audio format",
00506
00507
"JPEG image",
00508
"PNG image",
00509
"H.261 Video",
00510
"H.263 Video",
00511
"undefined",
00512
"undefined",
00513
"undefined",
00514
"undefined",
00515
"Maximum video format",
00516 };
00517
if ((codec >= 0) && (codec <= 24))
00518
return codecs[codec];
00519
else
00520
return "unknown";
00521 }
00522
00523
static int show_codecs(
int fd,
int argc,
char *argv[])
00524 {
00525
int i, found=0;
00526
00527
if ((argc < 2) || (argc > 3))
00528
return RESULT_SHOWUSAGE;
00529
00530
if (getenv(
"I_AM_NOT_AN_IDIOT") == NULL)
00531
ast_cli(fd,
"Disclaimer: this command is for informational purposes only.\n"
00532
"\tIt does not indicate anything about your configuration.\n");
00533
00534
if ((argc == 2) || (!strcasecmp(argv[1],
"audio"))) {
00535 found = 1;
00536
for (i=0;i<11;i++)
00537
ast_cli(fd,
"%11u (1 << %2d) %s\n",1 << i,i,
ast_codec2str(i));
00538 }
00539
00540
if ((argc == 2) || (!strcasecmp(argv[1],
"image"))) {
00541 found = 1;
00542
for (i=16;i<18;i++)
00543
ast_cli(fd,
"%11u (1 << %2d) %s\n",1 << i,i,
ast_codec2str(i));
00544 }
00545
00546
if ((argc == 2) || (!strcasecmp(argv[1],
"video"))) {
00547 found = 1;
00548
for (i=18;i<20;i++)
00549
ast_cli(fd,
"%11u (1 << %2d) %s\n",1 << i,i,
ast_codec2str(i));
00550 }
00551
00552
if (! found)
00553
return RESULT_SHOWUSAGE;
00554
else
00555
return RESULT_SUCCESS;
00556 }
00557
00558
static char frame_show_codecs_usage[] =
00559
"Usage: show [audio|video|image] codecs\n"
00560
" Displays codec mapping\n";
00561
00562 struct ast_cli_entry cli_show_codecs =
00563 { {
"show",
"codecs", NULL }, show_codecs,
"Shows codecs", frame_show_codecs_usage };
00564 struct ast_cli_entry cli_show_codecs_audio =
00565 { {
"show",
"audio",
"codecs", NULL }, show_codecs,
"Shows audio codecs", frame_show_codecs_usage };
00566 struct ast_cli_entry cli_show_codecs_video =
00567 { {
"show",
"video",
"codecs", NULL }, show_codecs,
"Shows video codecs", frame_show_codecs_usage };
00568 struct ast_cli_entry cli_show_codecs_image =
00569 { {
"show",
"image",
"codecs", NULL }, show_codecs,
"Shows image codecs", frame_show_codecs_usage };
00570
00571
static int show_codec_n(
int fd,
int argc,
char *argv[])
00572 {
00573
int codec, i, found=0;
00574
00575
if (argc != 3)
00576
return RESULT_SHOWUSAGE;
00577
00578
if (sscanf(argv[2],
"%d",&codec) != 1)
00579
return RESULT_SHOWUSAGE;
00580
00581
for (i=0;i<32;i++)
00582
if (codec & (1 << i)) {
00583 found = 1;
00584
ast_cli(fd,
"%11u (1 << %2d) %s\n",1 << i,i,
ast_codec2str(i));
00585 }
00586
00587
if (! found)
00588
ast_cli(fd,
"Codec %d not found\n", codec);
00589
00590
return RESULT_SUCCESS;
00591 }
00592
00593
static char frame_show_codec_n_usage[] =
00594
"Usage: show codec <number>\n"
00595
" Displays codec mapping\n";
00596
00597 struct ast_cli_entry cli_show_codec_n =
00598 { {
"show",
"codec", NULL }, show_codec_n,
"Shows a specific codec", frame_show_codec_n_usage };
00599
00600 void ast_frame_dump(
char *name,
struct ast_frame *f,
char *prefix)
00601 {
00602
char *n =
"unknown";
00603
char ftype[40] =
"Unknown Frametype";
00604
char cft[80];
00605
char subclass[40] =
"Unknown Subclass";
00606
char csub[80];
00607
char moreinfo[40] =
"";
00608
char cn[40];
00609
char cp[40];
00610
char cmn[40];
00611
if (name)
00612 n = name;
00613
if (!f) {
00614
ast_verbose(
"%s [ %s (NULL) ] [%s]\n",
00615
term_color(cp, prefix,
COLOR_BRMAGENTA,
COLOR_BLACK,
sizeof(cp)),
00616
term_color(cft,
"HANGUP",
COLOR_BRRED,
COLOR_BLACK,
sizeof(cft)),
00617
term_color(cn, n,
COLOR_YELLOW,
COLOR_BLACK,
sizeof(cn)));
00618
return;
00619 }
00620
00621
if (f->
frametype ==
AST_FRAME_VOICE)
00622
return;
00623
if (f->
frametype ==
AST_FRAME_VIDEO)
00624
return;
00625
switch(f->
frametype) {
00626
case AST_FRAME_DTMF:
00627 strcpy(ftype,
"DTMF");
00628 subclass[0] = f->
subclass;
00629 subclass[1] =
'\0';
00630
break;
00631
case AST_FRAME_CONTROL:
00632 strcpy(ftype,
"Control");
00633
switch(f->
subclass) {
00634
case AST_CONTROL_HANGUP:
00635 strcpy(subclass,
"Hangup");
00636
break;
00637
case AST_CONTROL_RING:
00638 strcpy(subclass,
"Ring");
00639
break;
00640
case AST_CONTROL_RINGING:
00641 strcpy(subclass,
"Ringing");
00642
break;
00643
case AST_CONTROL_ANSWER:
00644 strcpy(subclass,
"Answer");
00645
break;
00646
case AST_CONTROL_BUSY:
00647 strcpy(subclass,
"Busy");
00648
break;
00649
case AST_CONTROL_TAKEOFFHOOK:
00650 strcpy(subclass,
"Take Off Hook");
00651
break;
00652
case AST_CONTROL_OFFHOOK:
00653 strcpy(subclass,
"Line Off Hook");
00654
break;
00655
case AST_CONTROL_CONGESTION:
00656 strcpy(subclass,
"Congestion");
00657
break;
00658
case AST_CONTROL_FLASH:
00659 strcpy(subclass,
"Flash");
00660
break;
00661
case AST_CONTROL_WINK:
00662 strcpy(subclass,
"Wink");
00663
break;
00664
case AST_CONTROL_OPTION:
00665 strcpy(subclass,
"Option");
00666
break;
00667
case AST_CONTROL_RADIO_KEY:
00668 strcpy(subclass,
"Key Radio");
00669
break;
00670
case AST_CONTROL_RADIO_UNKEY:
00671 strcpy(subclass,
"Unkey Radio");
00672
break;
00673
default:
00674 snprintf(subclass,
sizeof(subclass),
"Unknown control '%d'", f->
subclass);
00675 }
00676
case AST_FRAME_NULL:
00677 strcpy(ftype,
"Null Frame");
00678 strcpy(subclass,
"N/A");
00679
break;
00680
case AST_FRAME_IAX:
00681
00682 strcpy(ftype,
"IAX Specific");
00683 snprintf(subclass,
sizeof(subclass),
"IAX Frametype %d", f->
subclass);
00684
break;
00685
case AST_FRAME_TEXT:
00686 strcpy(ftype,
"Text");
00687 strcpy(subclass,
"N/A");
00688 strncpy(moreinfo, f->
data,
sizeof(moreinfo) - 1);
00689
break;
00690
case AST_FRAME_IMAGE:
00691 strcpy(ftype,
"Image");
00692 snprintf(subclass,
sizeof(subclass),
"Image format %s\n",
ast_getformatname(f->
subclass));
00693
break;
00694
case AST_FRAME_HTML:
00695 strcpy(ftype,
"HTML");
00696
switch(f->
subclass) {
00697
case AST_HTML_URL:
00698 strcpy(subclass,
"URL");
00699 strncpy(moreinfo, f->
data,
sizeof(moreinfo) - 1);
00700
break;
00701
case AST_HTML_DATA:
00702 strcpy(subclass,
"Data");
00703
break;
00704
case AST_HTML_BEGIN:
00705 strcpy(subclass,
"Begin");
00706
break;
00707
case AST_HTML_END:
00708 strcpy(subclass,
"End");
00709
break;
00710
case AST_HTML_LDCOMPLETE:
00711 strcpy(subclass,
"Load Complete");
00712
break;
00713
case AST_HTML_NOSUPPORT:
00714 strcpy(subclass,
"No Support");
00715
break;
00716
case AST_HTML_LINKURL:
00717 strcpy(subclass,
"Link URL");
00718 strncpy(moreinfo, f->
data,
sizeof(moreinfo) - 1);
00719
break;
00720
case AST_HTML_UNLINK:
00721 strcpy(subclass,
"Unlink");
00722
break;
00723
case AST_HTML_LINKREJECT:
00724 strcpy(subclass,
"Link Reject");
00725
break;
00726
default:
00727 snprintf(subclass,
sizeof(subclass),
"Unknown HTML frame '%d'\n", f->
subclass);
00728
break;
00729 }
00730
break;
00731
default:
00732 snprintf(ftype,
sizeof(ftype),
"Unknown Frametype '%d'", f->
frametype);
00733 }
00734
if (!ast_strlen_zero(moreinfo))
00735
ast_verbose(
"%s [ TYPE: %s (%d) SUBCLASS: %s (%d) '%s' ] [%s]\n",
00736
term_color(cp, prefix,
COLOR_BRMAGENTA,
COLOR_BLACK,
sizeof(cp)),
00737
term_color(cft, ftype,
COLOR_BRRED,
COLOR_BLACK,
sizeof(cft)),
00738 f->
frametype,
00739
term_color(csub, subclass,
COLOR_BRCYAN,
COLOR_BLACK,
sizeof(csub)),
00740 f->
subclass,
00741
term_color(cmn, moreinfo,
COLOR_BRGREEN,
COLOR_BLACK,
sizeof(cmn)),
00742
term_color(cn, n,
COLOR_YELLOW,
COLOR_BLACK,
sizeof(cn)));
00743
else
00744
ast_verbose(
"%s [ TYPE: %s (%d) SUBCLASS: %s (%d) ] [%s]\n",
00745
term_color(cp, prefix,
COLOR_BRMAGENTA,
COLOR_BLACK,
sizeof(cp)),
00746
term_color(cft, ftype,
COLOR_BRRED,
COLOR_BLACK,
sizeof(cft)),
00747 f->
frametype,
00748
term_color(csub, subclass,
COLOR_BRCYAN,
COLOR_BLACK,
sizeof(csub)),
00749 f->
subclass,
00750
term_color(cn, n,
COLOR_YELLOW,
COLOR_BLACK,
sizeof(cn)));
00751
00752 }
00753
00754
00755
#ifdef TRACE_FRAMES
00756
static int show_frame_stats(
int fd,
int argc,
char *argv[])
00757 {
00758
struct ast_frame *f;
00759
int x=1;
00760
if (argc != 3)
00761
return RESULT_SHOWUSAGE;
00762
ast_cli(fd,
" Framer Statistics \n");
00763
ast_cli(fd,
"---------------------------\n");
00764
ast_cli(fd,
"Total allocated headers: %d\n", headers);
00765
ast_cli(fd,
"Queue Dump:\n");
00766
ast_mutex_lock(&framelock);
00767
for (f=headerlist; f; f = f->next) {
00768
ast_cli(fd,
"%d. Type %d, subclass %d from %s\n", x++, f->frametype, f->subclass, f->src ? f->src :
"<Unknown>");
00769 }
00770
ast_mutex_unlock(&framelock);
00771
return RESULT_SUCCESS;
00772 }
00773
00774
static char frame_stats_usage[] =
00775
"Usage: show frame stats\n"
00776
" Displays debugging statistics from framer\n";
00777
00778
struct ast_cli_entry cli_frame_stats =
00779 { {
"show",
"frame",
"stats", NULL }, show_frame_stats,
"Shows frame statistics", frame_stats_usage };
00780
#endif
00781
00782 int init_framer(
void)
00783 {
00784
#ifdef TRACE_FRAMES
00785
ast_cli_register(&cli_frame_stats);
00786
#endif
00787
ast_cli_register(&
cli_show_codecs);
00788
ast_cli_register(&
cli_show_codecs_audio);
00789
ast_cli_register(&
cli_show_codecs_video);
00790
ast_cli_register(&
cli_show_codecs_image);
00791
ast_cli_register(&
cli_show_codec_n);
00792
return 0;
00793 }