|
Definition at line 1409 of file dsp.c.
References ast_channel::_softhangup, AST_ALAW, ast_codec2str(), AST_CONTROL_ANSWER, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_RINGING, ast_dsp_busydetect(), AST_FORMAT_ALAW, AST_FORMAT_SLINEAR, AST_FORMAT_ULAW, AST_FRAME_CONTROL, AST_FRAME_DTMF, AST_FRAME_NULL, AST_FRAME_VOICE, ast_frfree(), ast_log(), AST_MULAW, ast_queue_frame(), AST_SOFTHANGUP_DEV, ast_frame::data, ast_frame::datalen, ast_dsp::digitmode, DSP_DIGITMODE_MF, DSP_DIGITMODE_MUTECONF, DSP_DIGITMODE_MUTEMAX, DSP_FEATURE_BUSY_DETECT, DSP_FEATURE_CALL_PROGRESS, DSP_FEATURE_DTMF_DETECT, DSP_FEATURE_SILENCE_SUPPRESS, ast_dsp::f, ast_dsp::features, FIX_INF, ast_frame::frametype, LOG_DEBUG, LOG_WARNING, ast_channel::name, ast_frame::subclass, ast_dsp::td, and ast_dsp::thinkdigit. 01410 {
01411 int silence;
01412 int res;
01413 int digit;
01414 int x;
01415 unsigned short *shortdata;
01416 unsigned char *odata;
01417 int len;
01418 int writeback = 0;
01419
01420 #define FIX_INF(inf) do { \
01421 if (writeback) { \
01422 switch(inf->subclass) { \
01423 case AST_FORMAT_SLINEAR: \
01424 break; \
01425 case AST_FORMAT_ULAW: \
01426 for (x=0;x<len;x++) \
01427 odata[x] = AST_LIN2MU(shortdata[x]); \
01428 break; \
01429 case AST_FORMAT_ALAW: \
01430 for (x=0;x<len;x++) \
01431 odata[x] = AST_LIN2A(shortdata[x]); \
01432 break; \
01433 } \
01434 } \
01435 } while(0)
01436
01437 if (!af)
01438 return NULL;
01439 if (af-> frametype != AST_FRAME_VOICE)
01440 return af;
01441 odata = af-> data;
01442 len = af-> datalen;
01443
01444 switch(af-> subclass) {
01445 case AST_FORMAT_SLINEAR:
01446 shortdata = af-> data;
01447 len = af-> datalen / 2;
01448 break;
01449 case AST_FORMAT_ULAW:
01450 shortdata = alloca(af-> datalen * 2);
01451 if (!shortdata) {
01452 ast_log(LOG_WARNING, "Unable to allocate stack space for data: %s\n", strerror(errno));
01453 return af;
01454 }
01455 for (x=0;x<len;x++)
01456 shortdata[x] = AST_MULAW(odata[x]);
01457 break;
01458 case AST_FORMAT_ALAW:
01459 shortdata = alloca(af-> datalen * 2);
01460 if (!shortdata) {
01461 ast_log(LOG_WARNING, "Unable to allocate stack space for data: %s\n", strerror(errno));
01462 return af;
01463 }
01464 for (x=0;x<len;x++)
01465 shortdata[x] = AST_ALAW(odata[x]);
01466 break;
01467 default:
01468 ast_log(LOG_WARNING, "Inband DTMF is not supported on codec %s. Use RFC2833\n", ast_codec2str(af-> subclass));
01469 return af;
01470 }
01471 silence = __ast_dsp_silence(dsp, shortdata, len, NULL);
01472 if ((dsp-> features & DSP_FEATURE_SILENCE_SUPPRESS) && silence) {
01473 memset(&dsp-> f, 0, sizeof(dsp-> f));
01474 dsp-> f. frametype = AST_FRAME_NULL;
01475 return &dsp-> f;
01476 }
01477 if ((dsp-> features & DSP_FEATURE_BUSY_DETECT) && ast_dsp_busydetect(dsp)) {
01478 chan-> _softhangup |= AST_SOFTHANGUP_DEV;
01479 memset(&dsp-> f, 0, sizeof(dsp-> f));
01480 dsp-> f. frametype = AST_FRAME_CONTROL;
01481 dsp-> f. subclass = AST_CONTROL_BUSY;
01482 ast_log(LOG_DEBUG, "Requesting Hangup because the busy tone was detected on channel %s\n", chan-> name);
01483 return &dsp-> f;
01484 }
01485 if ((dsp-> features & DSP_FEATURE_DTMF_DETECT)) {
01486 digit = __ast_dsp_digitdetect(dsp, shortdata, len, &writeback);
01487 #if 0
01488 if (digit)
01489 printf( "Performing digit detection returned %d, digitmode is %d\n", digit, dsp-> digitmode);
01490 #endif
01491 if (dsp-> digitmode & ( DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_MUTEMAX)) {
01492 if (!dsp-> thinkdigit) {
01493 if (digit) {
01494
01495 memset(&dsp-> f, 0, sizeof(dsp-> f));
01496 dsp-> f. frametype = AST_FRAME_DTMF;
01497 dsp-> f. subclass = 'm';
01498 dsp-> thinkdigit = 'x';
01499 FIX_INF(af);
01500 if (chan)
01501 ast_queue_frame(chan, af);
01502 ast_frfree(af);
01503 return &dsp-> f;
01504 }
01505 } else {
01506 if (digit) {
01507
01508 if (dsp-> thinkdigit) {
01509 if ((dsp-> thinkdigit != 'x') && (dsp-> thinkdigit != digit)) {
01510
01511
01512
01513 memset(&dsp-> f, 0, sizeof(dsp-> f));
01514 dsp-> f. frametype = AST_FRAME_DTMF;
01515 dsp-> f. subclass = dsp-> thinkdigit;
01516 FIX_INF(af);
01517 if (chan)
01518 ast_queue_frame(chan, af);
01519 ast_frfree(af);
01520 }
01521 dsp-> thinkdigit = digit;
01522 return &dsp-> f;
01523 }
01524 dsp-> thinkdigit = digit;
01525 } else {
01526 if (dsp-> thinkdigit) {
01527 memset(&dsp-> f, 0, sizeof(dsp-> f));
01528 if (dsp-> thinkdigit != 'x') {
01529
01530 dsp-> f. frametype = AST_FRAME_DTMF;
01531 dsp-> f. subclass = dsp-> thinkdigit;
01532 dsp-> thinkdigit = 0;
01533 } else {
01534 dsp-> f. frametype = AST_FRAME_DTMF;
01535 dsp-> f. subclass = 'u';
01536 dsp-> thinkdigit = 0;
01537 }
01538 FIX_INF(af);
01539 if (chan)
01540 ast_queue_frame(chan, af);
01541 ast_frfree(af);
01542 return &dsp-> f;
01543 }
01544 }
01545 }
01546 } else if (!digit) {
01547
01548 if (dsp-> digitmode & DSP_DIGITMODE_MF) {
01549 if (dsp-> td.mf.current_digits) {
01550 memset(&dsp-> f, 0, sizeof(dsp-> f));
01551 dsp-> f. frametype = AST_FRAME_DTMF;
01552 dsp-> f. subclass = dsp-> td.mf.digits[0];
01553 memmove(dsp-> td.mf.digits, dsp-> td.mf.digits + 1, dsp-> td.mf.current_digits);
01554 dsp-> td.mf.current_digits--;
01555 FIX_INF(af);
01556 if (chan)
01557 ast_queue_frame(chan, af);
01558 ast_frfree(af);
01559 return &dsp-> f;
01560 }
01561 } else {
01562 if (dsp-> td.dtmf.current_digits) {
01563 memset(&dsp-> f, 0, sizeof(dsp-> f));
01564 dsp-> f. frametype = AST_FRAME_DTMF;
01565 dsp-> f. subclass = dsp-> td.dtmf.digits[0];
01566 memmove(dsp-> td.dtmf.digits, dsp-> td.dtmf.digits + 1, dsp-> td.dtmf.current_digits);
01567 dsp-> td.dtmf.current_digits--;
01568 FIX_INF(af);
01569 if (chan)
01570 ast_queue_frame(chan, af);
01571 ast_frfree(af);
01572 return &dsp-> f;
01573 }
01574 }
01575 }
01576 }
01577 if ((dsp-> features & DSP_FEATURE_CALL_PROGRESS)) {
01578 res = __ast_dsp_call_progress(dsp, shortdata, len);
01579 memset(&dsp-> f, 0, sizeof(dsp-> f));
01580 dsp-> f. frametype = AST_FRAME_CONTROL;
01581 if (res) {
01582 switch(res) {
01583 case AST_CONTROL_ANSWER:
01584 case AST_CONTROL_BUSY:
01585 case AST_CONTROL_RINGING:
01586 case AST_CONTROL_CONGESTION:
01587 dsp-> f. subclass = res;
01588 if (chan)
01589 ast_queue_frame(chan, &dsp-> f);
01590 break;
01591 default:
01592 ast_log(LOG_WARNING, "Don't know how to represent call progress message %d\n", res);
01593 }
01594 }
01595 }
01596 FIX_INF(af);
01597 return af;
01598 }
|