chan_lcr: Select remote interface by chan_lcr
[lcr.git] / chan_lcr.c
index 302716e..657edf8 100644 (file)
@@ -513,43 +513,22 @@ void apply_opt(struct chan_call *call, char *data)
                        break;
 #endif
                case 'f':
-                       if (opt[1] == '\0') {
-                               CERROR(call, call->ast, "Option 'f' (faxdetect) expects parameter.\n", opt);
+                       if (opt[1] != '\0') {
+                               CERROR(call, call->ast, "Option 'f' (faxdetect) expects no parameter.\n", opt);
                                break;
                        }
-                       call->faxdetect=atoi(opt+1);
-                       if (!call->dsp)
-                               call->dsp=ast_dsp_new();
-                       if (call->dsp) {
-                               #ifdef LCR_FOR_CALLWEAVER
-                               ast_dsp_set_features(call->dsp, DSP_FEATURE_DTMF_DETECT| DSP_FEATURE_FAX_CNG_DETECT);
-                               #endif
-                               #ifdef LCR_FOR_ASTERISK
-                               #ifdef DSP_FEATURE_DTMF_DETECT
-                               ast_dsp_set_features(call->dsp, DSP_FEATURE_DTMF_DETECT| DSP_FEATURE_FAX_DETECT);
-                               #else
-                               ast_dsp_set_features(call->dsp, DSP_FEATURE_DIGIT_DETECT| DSP_FEATURE_FAX_DETECT);
-                               #endif
-
-                               #endif
-                               if (!call->trans) {
-                                       #ifdef LCR_FOR_CALLWEAVER
-                                       call->trans=ast_translator_build_path(AST_FORMAT_SLINEAR, 8000, (options.law=='a')?AST_FORMAT_ALAW:AST_FORMAT_ULAW, 8000);
-                                       #endif
-                                       #ifdef LCR_FOR_ASTERISK
-                                       #if ASTERISK_VERSION_NUM < 100000
-                                       call->trans=ast_translator_build_path(AST_FORMAT_SLINEAR, (options.law=='a')?AST_FORMAT_ALAW:AST_FORMAT_ULAW);
-                                       #else
-                                       struct ast_format src;
-                                       struct ast_format dst;
-                                       ast_format_set(&dst, AST_FORMAT_SLINEAR, 0);
-                                       ast_format_set(&dst,(options.law=='a')?AST_FORMAT_ALAW:AST_FORMAT_ULAW , 0);
-                                       call->trans=ast_translator_build_path(&dst, &src);
-                                       #endif
-                                       #endif
-                               }
+                       call->faxdetect = 1;
+                       call->dsp_dtmf = 0;
+                       CDEBUG(call, call->ast, "Option 'f' (faxdetect).\n");
+                       break;
+               case 'a':
+                       if (opt[1] != '\0') {
+                               CERROR(call, call->ast, "Option 'a' (asterisk DTMF) expects no parameter.\n", opt);
+                               break;
                        }
-                       CDEBUG(call, call->ast, "Option 'f' (faxdetect) with config '%s'.\n", call->faxdetect);
+                       call->ast_dsp = 1;
+                       call->dsp_dtmf = 0;
+                       CDEBUG(call, call->ast, "Option 'a' (Asterisk DTMF detection).\n");
                        break;
                case 'r':
                        if (opt[1] != '\0') {
@@ -604,6 +583,40 @@ void apply_opt(struct chan_call *call, char *data)
                        CERROR(call, call->ast, "Option '%s' unknown.\n", opt);
                }
        }
+
+       if (call->faxdetect || call->ast_dsp) {
+               if (!call->dsp)
+                       call->dsp=ast_dsp_new();
+               if (call->dsp) {
+                       #ifdef LCR_FOR_CALLWEAVER
+                       ast_dsp_set_features(call->dsp, DSP_FEATURE_DTMF_DETECT | ((call->faxdetect) ? DSP_FEATURE_FAX_CNG_DETECT : 0));
+                       #endif
+                       #ifdef LCR_FOR_ASTERISK
+                       #ifdef DSP_FEATURE_DTMF_DETECT
+                       ast_dsp_set_features(call->dsp, DSP_FEATURE_DTMF_DETECT | ((call->faxdetect) ? DSP_FEATURE_FAX_DETECT : 0));
+                       #else
+                       ast_dsp_set_features(call->dsp, DSP_FEATURE_DIGIT_DETECT | ((call->faxdetect) ? DSP_FEATURE_FAX_DETECT : 0));
+                       #endif
+
+                       #endif
+                       if (!call->trans) {
+                               #ifdef LCR_FOR_CALLWEAVER
+                               call->trans=ast_translator_build_path(AST_FORMAT_SLINEAR, 8000, (options.law=='a')?AST_FORMAT_ALAW:AST_FORMAT_ULAW, 8000);
+                               #endif
+                               #ifdef LCR_FOR_ASTERISK
+                               #if ASTERISK_VERSION_NUM < 100000
+                               call->trans=ast_translator_build_path(AST_FORMAT_SLINEAR, (options.law=='a')?AST_FORMAT_ALAW:AST_FORMAT_ULAW);
+//                             #else
+//                             struct ast_format src;
+//                             struct ast_format dst;
+//                             ast_format_set(&dst, AST_FORMAT_SLINEAR, 0);
+//                             ast_format_set(&dst,(options.law=='a')?AST_FORMAT_ALAW:AST_FORMAT_ULAW , 0);
+//                             call->trans=ast_translator_build_path(&dst, &src);
+                               #endif
+                               #endif
+                       }
+               }
+       }
 }
 
 /*
@@ -633,8 +646,6 @@ static void send_setup_to_lcr(struct chan_call *call)
                strncpy(newparam.setup.dialinginfo.keypad, call->dialstring, sizeof(newparam.setup.dialinginfo.keypad)-1);
        else
                strncpy(newparam.setup.dialinginfo.id, call->dialstring, sizeof(newparam.setup.dialinginfo.id)-1);
-       if (!!strcmp(call->interface, "pbx"))
-               strncpy(newparam.setup.dialinginfo.interfaces, call->interface, sizeof(newparam.setup.dialinginfo.interfaces)-1);
        newparam.setup.callerinfo.itype = INFO_ITYPE_CHAN;
        newparam.setup.callerinfo.ntype = INFO_NTYPE_UNKNOWN;
        strncpy(newparam.setup.callerinfo.display, call->display, sizeof(newparam.setup.callerinfo.display)-1);
@@ -1427,8 +1438,21 @@ static void lcr_in_information(struct chan_call *call, int message_type, union p
 
        /* use bridge to forware message not supported by asterisk */
        if (call->state == CHAN_LCR_STATE_CONNECT) {
-               CDEBUG(call, call->ast, "Call is connected, bridging.\n");
-               bridge_message_if_bridged(call, message_type, param);
+               if (call->bridge_call) {
+                       CDEBUG(call, call->ast, "Call is connected, bridging.\n");
+                       bridge_message_if_bridged(call, message_type, param);
+               } else {
+                       if (call->dsp_dtmf) {
+                               if (!wake_global) {
+                                       wake_global = 1;
+                                       char byte = 0;
+                                       int rc;
+                                       rc = write(wake_pipe[1], &byte, 1);
+                               }
+                               strncat(call->queue_string, param->information.id, sizeof(call->queue_string)-1);
+                       } else
+                               CDEBUG(call, call->ast, "LCR's DTMF detection is disabled.\n");
+               }
        }
 }
 
@@ -1505,7 +1529,7 @@ void lcr_in_dtmf(struct chan_call *call, int val)
                return;
 
        if (!call->dsp_dtmf) {
-               CDEBUG(call, call->ast, "Recognised DTMF digit '%c', but ignoring. This is fixed in later mISDN driver.\n", val);
+               CDEBUG(call, call->ast, "Recognised DTMF digit '%c' by LCR, but ignoring. (disabled by option)\n", val);
                return;
        }
 
@@ -1580,6 +1604,7 @@ int receive_message(int message_type, unsigned int ref, union parameter *param)
                                return 0;
                        }
                }
+               send_message(MESSAGE_ENABLEKEYPAD, call->ref, &newparam);
                return 0;
        }
 
@@ -1659,6 +1684,10 @@ int receive_message(int message_type, unsigned int ref, union parameter *param)
                rc = write(call->pipe[1], param->traffic.data, param->traffic.len);
                break;
 
+               case MESSAGE_DTMF:
+               lcr_in_dtmf(call, param->dtmf);
+               break;
+
                default:
                CDEBUG(call, call->ast, "Message %d from LCR unhandled.\n", message_type);
                break;
@@ -2394,6 +2423,7 @@ static int lcr_call(struct ast_channel *ast, char *dest, int timeout)
        /* send MESSAGE_NEWREF */
        memset(&newparam, 0, sizeof(union parameter));
        newparam.newref.direction = 0; /* request from app */
+       strncpy(newparam.newref.interface, call->interface, sizeof(newparam.newref.interface) - 1);
        send_message(MESSAGE_NEWREF, 0, &newparam);
 
        /* set hdlc if capability requires hdlc */
@@ -2750,12 +2780,13 @@ static int lcr_write(struct ast_channel *ast, struct ast_frame *fr)
 #else
        call = ast_channel_tech_pvt(ast);
 #endif
-       if (!call) {
+       if (!call || !call->ref) {
+               /* drop the frame, if no ref exists, but return successfull delivery, or asterisk will abort connection */
                ast_mutex_unlock(&chan_lock);
                if (f != fr) {
                        ast_frfree(f);
                }
-               return -1;
+               return 0;
        }
        len = f->samples;
        p = *((unsigned char **)&(f->data));
@@ -2781,6 +2812,7 @@ static struct ast_frame *lcr_read(struct ast_channel *ast)
 {
        struct chan_call *call;
        int len = 0;
+       struct ast_frame *f = NULL;
 
        ast_mutex_lock(&chan_lock);
 #if ASTERISK_VERSION_NUM < 110000
@@ -2860,8 +2892,17 @@ static struct ast_frame *lcr_read(struct ast_channel *ast)
        }
        call->read_fr.delivery = ast_tv(0,0);
        *((unsigned char **)&(call->read_fr.data)) = call->read_buff;
+
+       if (call->dsp)
+               f = ast_dsp_process(ast, call->dsp, &call->read_fr);
+       if (f && f->frametype == AST_FRAME_DTMF)
+               CDEBUG(call, ast, "Asterisk detected inband DTMF: %c.\n", f->subclass.integer);
+
        ast_mutex_unlock(&chan_lock);
 
+       if (f && f->frametype == AST_FRAME_DTMF)
+               return f;
+
        return &call->read_fr;
 }
 
@@ -3495,18 +3536,18 @@ int load_module(void)
                                 "\n"
                                 "The available options are:\n"
                                 "    d - Send display text on called phone, text is the optarg.\n"
-                                "    n - Don't detect dtmf tones on called channel.\n"
+                                "    n - Don't detect dtmf tones from LCR.\n"
                                 "    h - Force data call (HDLC).\n"
                                 "    q - Add queue to make fax stream seamless (required for fax app).\n"
                                 "        Use queue size in miliseconds for optarg. (try 250)\n"
-                                "    f - Adding fax detection. It it timeouts, mISDN_dsp is used.\n"
-                                "        Use time to detect for optarg.\n"
+                                "    a - Adding DTMF detection.\n"
+                                "    f - Adding fax detection.\n"
 #if 0
                                 "    c - Make crypted outgoing call, optarg is keyindex.\n"
                                 "    e - Perform echo cancelation on this channel.\n"
 #endif
                                 "        Takes mISDN pipeline option as optarg.\n"
-                                "    s - Send Non Inband DTMF as inband.\n"
+                                "    s - Send Non Inband DTMF as inband. (disables LCR's DTMF)\n"
                                 "    r - re-buffer packets (160 bytes). Required for some SIP-phones and fax applications.\n"
 #if 0
                                 "   vr - rxgain control\n"