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