chan_lcr: fixed some "bridging typos"
[lcr.git] / chan_lcr.c
index b00bc7e..ee5ae6b 100644 (file)
@@ -21,8 +21,9 @@ Now the channel driver is linked to LCR and can receive and make calls.
 Call is initiated by LCR:
 
 If a call is received from LCR, a MESSAGE_NEWREF is received first.
+The ref_was_assigned ist set to 1.
 A new chan_call instance is created. The call reference (ref) is given by
-MESSAGE_NEWREF. The state is CHAN_LCR_STATE_IN_PREPARE.
+the received MESSAGE_NEWREF. The state is CHAN_LCR_STATE_IN_PREPARE.
 After receiving MESSAGE_SETUP from LCR, the ast_channel instance is created
 using ast_channel_alloc(1).  The setup information is given to asterisk.
 The new Asterisk instance pointer (ast) is stored to chan_call structure.
@@ -34,8 +35,9 @@ Call is initiated by Asterisk:
 If a call is requested from Asterisk, a new chan_call instance is created.
 The new Asterisk instance pointer (ast) is stored to chan_call structure.
 The current call ref is set to 0, the state is CHAN_LCR_STATE_OUT_PREPARE.
-If the call is received (lcr_call) A MESSASGE_NEWREF is sent to LCR requesting
+If the call is received (lcr_call) A MESSAGE_NEWREF is sent to LCR requesting
 a new call reference (ref).
+The ref_was_assigned ist set to 1.
 Further dialing information is queued.
 After the new callref is received by special MESSAGE_NEWREF reply, new ref
 is stored in the chan_call structure. 
@@ -57,6 +59,7 @@ Call is released by LCR:
 
 A MESSAGE_RELEASE is received with the call reference (ref) to be released.
 The current ref is set to 0, to indicate released reference.
+The ref_was_assigned==1 shows that there is no other ref to be assigned.
 The state changes to CHAN_LCR_STATE_RELEASE.
 ast_queue_hangup() is called, if asterisk instance (ast) exists, if not,
 the chan_call instance is destroyed.
@@ -73,6 +76,7 @@ lcr_hangup() is called-back by Asterisk. If the call reference (ref) is set,
 a MESSAGE_RELEASE is sent to LCR and the chan_call instance is destroyed.
 If the ref is 0 and the state is not CHAN_LCR_STATE_RELEASE, the new state is
 set to CHAN_LCR_STATE_RELEASE.
+The ref_was_assigned==0 shows that a ref is still requested.
 Later, if the MESSAGE_NEWREF reply is received, a MESSAGE_RELEASE is sent to
 LCR and the chan_call instance is destroyed.
 If the ref is 0 and the state is CHAN_LCR_STATE_RELEASE, see the proceedure
@@ -461,7 +465,6 @@ void apply_opt(struct chan_call *call, char *data)
                        CDEBUG(call, call->ast, "Option 'r' (re-buffer 160 bytes)");
                        call->rebuffer = 1;
                        break;
-#if 0
                case 's':
                        if (opt[1] != '\0') {
                                CERROR(call, call->ast, "Option 's' (inband DTMF) expects no parameter.\n", opt);
@@ -469,9 +472,7 @@ void apply_opt(struct chan_call *call, char *data)
                        }
                        CDEBUG(call, call->ast, "Option 's' (inband DTMF).\n");
                        call->inband_dtmf = 1;
-todo
                        break;
-#endif
                case 'v':
                        if (opt[1] != 'r' && opt[1] != 't') {
                                CERROR(call, call->ast, "Option 'v' (volume) expects parameter.\n", opt);
@@ -614,7 +615,7 @@ static void bridge_message_if_bridged(struct chan_call *call, int message_type,
        /* check bridge */
        if (!call) return;
        if (!call->bridge_call) return;
-       CDEBUG(call, NULL, "Sending message due briding.\n");
+       CDEBUG(call, NULL, "Sending message due bridging.\n");
        send_message(message_type, call->bridge_call->ref, param);
 }
 
@@ -992,7 +993,7 @@ 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, briding.\n");
+               CDEBUG(call, call->ast, "Call is connected, bridging.\n");
                bridge_message_if_bridged(call, message_type, param);
        }
 }
@@ -1755,6 +1756,42 @@ static int lcr_call(struct ast_channel *ast, char *dest, int timeout)
        return 0; 
 }
 
+static void send_digit_to_chan(struct ast_channel * ast, char digit )
+{
+        static const char* dtmf_tones[] = {
+                "!941+1336/100,!0/100", /* 0 */
+                "!697+1209/100,!0/100", /* 1 */
+                "!697+1336/100,!0/100", /* 2 */
+                "!697+1477/100,!0/100", /* 3 */
+                "!770+1209/100,!0/100", /* 4 */
+                "!770+1336/100,!0/100", /* 5 */
+                "!770+1477/100,!0/100", /* 6 */
+                "!852+1209/100,!0/100", /* 7 */
+                "!852+1336/100,!0/100", /* 8 */
+                "!852+1477/100,!0/100", /* 9 */
+                "!697+1633/100,!0/100", /* A */
+                "!770+1633/100,!0/100", /* B */
+                "!852+1633/100,!0/100", /* C */
+                "!941+1633/100,!0/100", /* D */
+                "!941+1209/100,!0/100", /* * */
+                "!941+1477/100,!0/100" };       /* # */
+
+        if (digit >= '0' && digit <='9')
+                ast_playtones_start(ast,0,dtmf_tones[digit-'0'], 0);
+        else if (digit >= 'A' && digit <= 'D')
+                ast_playtones_start(ast,0,dtmf_tones[digit-'A'+10], 0);
+        else if (digit == '*')
+                ast_playtones_start(ast,0,dtmf_tones[14], 0);
+        else if (digit == '#')
+                ast_playtones_start(ast,0,dtmf_tones[15], 0);
+        else {
+                /* not handled */
+                ast_log(LOG_DEBUG, "Unable to handle DTMF tone "
+                       "'%c' for '%s'\n", digit, ast->name);
+        }
+}
+
+
 static int lcr_digit_begin(struct ast_channel *ast, char digit)
 {
         struct chan_call *call;
@@ -1798,7 +1835,34 @@ static int lcr_digit_begin(struct ast_channel *ast, char digit)
 
 static int lcr_digit_end(struct ast_channel *ast, char digit, unsigned int duration)
 {
-       printf("DIGIT END %c\n", digit);
+       int inband_dtmf = 0;
+        struct chan_call *call;
+
+       ast_mutex_lock(&chan_lock);
+
+        call = ast->tech_pvt;
+
+       if (!call) {
+               CERROR(NULL, ast, 
+                      "Received digit from Asterisk, "
+                      "but no call instance exists.\n");
+               ast_mutex_unlock(&chan_lock);
+               return -1;
+       }
+
+       CDEBUG(call, ast, "DIGIT END '%c' from Asterisk.\n", digit);
+
+       if (call->state == CHAN_LCR_STATE_CONNECT && call->inband_dtmf) {
+               inband_dtmf = 1;
+       }
+
+       ast_mutex_unlock(&chan_lock);
+
+       if (inband_dtmf) {
+               CDEBUG(call, ast, "-> sending '%c' inband.\n", digit);
+               send_digit_to_chan(ast, digit);
+       }
+
        return (0);
 }
 
@@ -2142,7 +2206,7 @@ enum ast_bridge_result lcr_bridge(struct ast_channel *ast1,
        struct ast_frame        *f;
        int                     bridge_id;
 
-       CDEBUG(NULL, NULL, "Received briding request from Asterisk.\n");
+       CDEBUG(NULL, NULL, "Received bridging request from Asterisk.\n");
 
        carr[0] = ast1;
        carr[1] = ast2;
@@ -2159,7 +2223,7 @@ enum ast_bridge_result lcr_bridge(struct ast_channel *ast1,
 
        /* join, if both call instances uses dsp */
        if (!call1->nodsp && !call2->nodsp) {
-               CDEBUG(NULL, NULL, "Both calls use DSP, briding via DSP.\n");
+               CDEBUG(NULL, NULL, "Both calls use DSP, bridging via DSP.\n");
 
                /* get bridge id and join */
                bridge_id = new_bridge_id();
@@ -2173,9 +2237,9 @@ enum ast_bridge_result lcr_bridge(struct ast_channel *ast1,
                        bchannel_join(call2->bchannel, bridge_id);
        } else
        if (call1->nodsp && call2->nodsp)
-               CDEBUG(NULL, NULL, "Both calls use no DSP, briding in channel driver.\n");
+               CDEBUG(NULL, NULL, "Both calls use no DSP, bridging in channel driver.\n");
        else
-               CDEBUG(NULL, NULL, "One call uses no DSP, briding in channel driver.\n");
+               CDEBUG(NULL, NULL, "One call uses no DSP, bridging in channel driver.\n");
        call1->bridge_call = call2;
        call2->bridge_call = call1;
 
@@ -2258,7 +2322,7 @@ enum ast_bridge_result lcr_bridge(struct ast_channel *ast1,
     
        }
        
-       CDEBUG(NULL, NULL, "Releasing bride.\n");
+       CDEBUG(NULL, NULL, "Releasing bridge.\n");
 
        /* split channels */
        ast_mutex_lock(&chan_lock);
@@ -2469,7 +2533,7 @@ int load_module(void)
                                 "    c - Make crypted outgoing call, optarg is keyindex.\n"
                                 "    e - Perform echo cancelation on this channel.\n"
                                 "        Takes mISDN pipeline option as optarg.\n"
-//                              "    s - Send Non Inband DTMF as inband.\n"
+                                "    s - Send Non Inband DTMF as inband.\n"
                                 "   vr - rxgain control\n"
                                 "   vt - txgain control\n"
                                 "        Volume changes at factor 2 ^ optarg.\n"