- Fixed HLC (higher layer capability) modification to LCR routing.
authorAndreas Eversberg <jolly@eversberg.eu>
Sun, 24 Jan 2010 18:41:32 +0000 (19:41 +0100)
committerAndreas Eversberg <jolly@eversberg.eu>
Sun, 24 Jan 2010 18:41:32 +0000 (19:41 +0100)
- Fixed chan_lcr fax queue buffer. Added LCR_TRANSFERCAPABILITY environment.

-> use options "n:t:q250" for sending/receiving faxes with asterisk and chan_lcr.

modified:   README
modified:   action.cpp
modified:   bchannel.c
modified:   chan_lcr.c
modified:   route.c
modified:   route.h

README
action.cpp
bchannel.c
chan_lcr.c
route.c
route.h

diff --git a/README b/README
index 07c26ac..9b8aae1 100644 (file)
--- a/README
+++ b/README
@@ -537,6 +537,8 @@ Changes after Version 1.7
 - Added "release" action and timeout to "execute" action.
 - Added queue buffer for chan_lcr sending faxes without interruption.
   -> Use options "t:q250" for disabling mISDN_dsp and adding a 250ms delay.
 - Added "release" action and timeout to "execute" action.
 - Added queue buffer for chan_lcr sending faxes without interruption.
   -> Use options "t:q250" for disabling mISDN_dsp and adding a 250ms delay.
+- Fixed HLC (higher layer capability) modification to LCR routing.
+- Fixed chan_lcr fax queue buffer. Added LCR_TRANSFERCAPABILITY environment.
 
 
 
 
 
 
index aa83304..62f63ed 100644 (file)
@@ -111,6 +111,8 @@ void EndpointAppPBX::action_dialing_internal(void)
                        capainfo.bearer_mode = INFO_BMODE_PACKET;
                }
                capainfo.bearer_info1 = INFO_INFO1_NONE;
                        capainfo.bearer_mode = INFO_BMODE_PACKET;
                }
                capainfo.bearer_info1 = INFO_INFO1_NONE;
+               capainfo.hlc = INFO_HLC_NONE;
+               capainfo.exthlc = INFO_HLC_NONE;
        }
        if ((rparam = routeparam(e_action, PARAM_BMODE))) {
                capainfo.bearer_mode = rparam->integer_value;
        }
        if ((rparam = routeparam(e_action, PARAM_BMODE))) {
                capainfo.bearer_mode = rparam->integer_value;
@@ -237,6 +239,8 @@ void EndpointAppPBX::action_dialing_external(void)
                        capainfo.bearer_mode = INFO_BMODE_PACKET;
                }
                capainfo.bearer_info1 = INFO_INFO1_NONE;
                        capainfo.bearer_mode = INFO_BMODE_PACKET;
                }
                capainfo.bearer_info1 = INFO_INFO1_NONE;
+               capainfo.hlc = INFO_HLC_NONE;
+               capainfo.exthlc = INFO_HLC_NONE;
        }
        if ((rparam = routeparam(e_action, PARAM_BMODE))) {
                capainfo.bearer_mode = rparam->integer_value;
        }
        if ((rparam = routeparam(e_action, PARAM_BMODE))) {
                capainfo.bearer_mode = rparam->integer_value;
index 51423a1..b6107b6 100644 (file)
@@ -449,9 +449,9 @@ void bchannel_transmit(struct bchannel *bchannel, unsigned char *data, int len)
        bchannel->test = (bchannel->test + len) & 7;
 #endif
        if (bchannel->nodsp_queue) {
        bchannel->test = (bchannel->test + len) & 7;
 #endif
        if (bchannel->nodsp_queue) {
-               space = (bchannel->nodsp_queue_out - bchannel->nodsp_queue_in) & (QUEUE_BUFFER_SIZE - 1);
+               space = (bchannel->nodsp_queue_out - bchannel->nodsp_queue_in - 1) & (QUEUE_BUFFER_SIZE - 1);
                if (len > space) {
                if (len > space) {
-                       CERROR(bchannel->call, NULL, "Queue buffer overflow.\n");
+                       CERROR(bchannel->call, NULL, "Queue buffer overflow, space is %d, len is %d.\n", space, len);
                        return;
                }
                p = buff + MISDN_HEADER_LEN;
                        return;
                }
                p = buff + MISDN_HEADER_LEN;
@@ -485,6 +485,11 @@ static void bchannel_send_queue(struct bchannel *bchannel)
        len = (bchannel->nodsp_queue_in - bchannel->nodsp_queue_out) & (QUEUE_BUFFER_SIZE - 1);
        if (len == 0)
                return; /* mISDN driver received all load */
        len = (bchannel->nodsp_queue_in - bchannel->nodsp_queue_out) & (QUEUE_BUFFER_SIZE - 1);
        if (len == 0)
                return; /* mISDN driver received all load */
+#if 0
+       printf("%4d:(%s|%s)\n", bchannel->nodsp_queue_out,
+               "----------------------------------------------------------------"+64-len/(8192/64),
+               "                                                                "+len/(8192/64));
+#endif
        if (len > 1024)
                len = 1024;
        frm->prim = PH_DATA_REQ;
        if (len > 1024)
                len = 1024;
        frm->prim = PH_DATA_REQ;
index 0013f2f..040f921 100644 (file)
@@ -612,6 +612,7 @@ static void send_setup_to_lcr(struct chan_call *call)
 {
        union parameter newparam;
        struct ast_channel *ast = call->ast;
 {
        union parameter newparam;
        struct ast_channel *ast = call->ast;
+       const char *tmp;
 
        if (!call->ast || !call->ref)
                return;
 
        if (!call->ast || !call->ref)
                return;
@@ -664,6 +665,9 @@ static void send_setup_to_lcr(struct chan_call *call)
                default:
                newparam.setup.callerinfo.ntype = INFO_NTYPE_UNKNOWN;
        }
                default:
                newparam.setup.callerinfo.ntype = INFO_NTYPE_UNKNOWN;
        }
+       tmp = pbx_builtin_getvar_helper(ast, "LCR_TRANSFERCAPABILITY");
+       if (tmp && *tmp)
+               ast->transfercapability = atoi(tmp);
        newparam.setup.capainfo.bearer_capa = ast->transfercapability;
        newparam.setup.capainfo.bearer_mode = INFO_BMODE_CIRCUIT;
        if (call->hdlc)
        newparam.setup.capainfo.bearer_capa = ast->transfercapability;
        newparam.setup.capainfo.bearer_mode = INFO_BMODE_CIRCUIT;
        if (call->hdlc)
@@ -2823,6 +2827,12 @@ int load_module(void)
                                 "   vt - txgain control\n"
                                 "        Volume changes at factor 2 ^ optarg.\n"
                                 "    k - use keypad to dial this call.\n"
                                 "   vt - txgain control\n"
                                 "        Volume changes at factor 2 ^ optarg.\n"
                                 "    k - use keypad to dial this call.\n"
+                                "\n"
+                                "set LCR_TRANSFERCAPABILITY to the numerical bearer capabilty in order to alter caller's capability\n"
+                                " -> use 16 for fax (3.1k audio)\n"
+                                "\n"
+                                "To send a fax, you need to set LCR_TRANSFERCAPABILITY environment to 16, also you need to set\n"
+                                "options: \"n:t:q250\" for seamless audio transmission.\n"
                );
 
  
                );
 
  
diff --git a/route.c b/route.c
index 959b584..aaa5606 100644 (file)
--- a/route.c
+++ b/route.c
@@ -68,8 +68,8 @@ struct cond_defs cond_defs[] = {
          "capability=speech|audio|video|digital-restricted|digital-unrestricted|digital-unrestricted-tones[,...]", "Matches the given bearer capability(s)."},
        { "infolayer1", MATCH_INFOLAYER1, COND_TYPE_INTEGER,
          "infolayer1=<value>[,...]", "Matches the given information layer 1. (2=u-Law, 3=a-law, see info layer 1 in bearer capability.)"},
          "capability=speech|audio|video|digital-restricted|digital-unrestricted|digital-unrestricted-tones[,...]", "Matches the given bearer capability(s)."},
        { "infolayer1", MATCH_INFOLAYER1, COND_TYPE_INTEGER,
          "infolayer1=<value>[,...]", "Matches the given information layer 1. (2=u-Law, 3=a-law, see info layer 1 in bearer capability.)"},
-       { "hlc",        MATCH_HLC,      COND_TYPE_INTEGER,
-         "hlc=<value>[,...]", "Matches the high layer capability(s)."},
+       { "hlc",        MATCH_HLC,      COND_TYPE_HLC,
+         "hlc=telephony|faxg2g3|faxg4|teletex1|teletex2|teletex3|videotex1|videotex2|telex|mhs|osi|maintenance|management|audiovisual[,...]", "Matches the high layer capability(s)."},
        { "file",       MATCH_FILE,     COND_TYPE_STRING,
          "file=<path>[,...]", "Mathes is the given file exists and if the first character is '1'."},
        { "execute",    MATCH_EXECUTE,  COND_TYPE_STRING,
        { "file",       MATCH_FILE,     COND_TYPE_STRING,
          "file=<path>[,...]", "Mathes is the given file exists and if the first character is '1'."},
        { "execute",    MATCH_EXECUTE,  COND_TYPE_STRING,
@@ -126,11 +126,11 @@ struct param_defs param_defs[] = {
          "infolayer1", PARAM_TYPE_INTEGER,
          "infolayer1=<value>", "Alter the layer 1 information of a call. Use 3 for ALAW or 2 for uLAW."},
        { PARAM_HLC,
          "infolayer1", PARAM_TYPE_INTEGER,
          "infolayer1=<value>", "Alter the layer 1 information of a call. Use 3 for ALAW or 2 for uLAW."},
        { PARAM_HLC,
-         "hlc",        PARAM_TYPE_INTEGER,
-         "hlc=<value>", "Alter the HLC identification. Use 1 for telephony or omit."},
+         "hlc",        PARAM_TYPE_HLC,
+         "hlc=telephony|faxg2g3|faxg4|teletex1|teletex2|teletex3|videotex1|videotex2|telex|mhs|osi|maintenance|management|audiovisual", "Alter the HLC identification."},
        { PARAM_EXTHLC,
        { PARAM_EXTHLC,
-         "exthlc",     PARAM_TYPE_INTEGER,
-         "exthlc=<value>", "Alter extended HLC value. (Mainenance only, don't use it.)"},
+         "exthlc",     PARAM_TYPE_HLC,
+         "exthlc=<value>", "Alter extended HLC value, see hlc. (Mainenance only, don't use it.)"},
        { PARAM_PRESENT,
          "present",    PARAM_TYPE_YESNO,
          "present=yes|no", "Allow or restrict caller ID regardless what the caller wants."},
        { PARAM_PRESENT,
          "present",    PARAM_TYPE_YESNO,
          "present=yes|no", "Allow or restrict caller ID regardless what the caller wants."},
@@ -1252,6 +1252,43 @@ struct route_ruleset *ruleset_parse(void)
                                cond->value_type = VALUE_TYPE_INTEGER;
                                break;
 
                                cond->value_type = VALUE_TYPE_INTEGER;
                                break;
 
+                               /* parse service value */
+                               case COND_TYPE_HLC:
+                               if (!strncasecmp("telephony", p, 9))
+                                       cond->integer_value = INFO_HLC_TELEPHONY;
+                               else if (!strncasecmp("faxg2g3", p, 7))
+                                       cond->integer_value = INFO_HLC_FAXG2G3;
+                               else if (!strncasecmp("faxg4", p, 5))
+                                       cond->integer_value = INFO_HLC_FAXG4;
+                               else if (!strncasecmp("teletex1", p, 8))
+                                       cond->integer_value = INFO_HLC_TELETEX1;
+                               else if (!strncasecmp("teletex2", p, 8))
+                                       cond->integer_value = INFO_HLC_TELETEX2;
+                               else if (!strncasecmp("teletex3", p, 8))
+                                       cond->integer_value = INFO_HLC_TELETEX3;
+                               else if (!strncasecmp("videotex1", p, 9))
+                                       cond->integer_value = INFO_HLC_VIDEOTEX1;
+                               else if (!strncasecmp("videotex2", p, 9))
+                                       cond->integer_value = INFO_HLC_VIDEOTEX2;
+                               else if (!strncasecmp("telex", p, 5))
+                                       cond->integer_value = INFO_HLC_TELEX;
+                               else if (!strncasecmp("mhs", p, 3))
+                                       cond->integer_value = INFO_HLC_MHS;
+                               else if (!strncasecmp("osi", p, 3))
+                                       cond->integer_value = INFO_HLC_OSI;
+                               else if (!strncasecmp("maintenance", p, 11))
+                                       cond->integer_value = INFO_HLC_MAINTENANCE;
+                               else if (!strncasecmp("management", p, 10))
+                                       cond->integer_value = INFO_HLC_MANAGEMENT;
+                               else if (!strncasecmp("audiovisual", p, 11))
+                                       cond->integer_value = INFO_HLC_AUDIOVISUAL;
+                               else {
+                                       SPRINT(failure, "Given HLC type is invalid or misspelled.");
+                                       goto parse_error;
+                               }
+                               cond->value_type = VALUE_TYPE_INTEGER;
+                               break;
+
                                /* parse interface attribute <if>:<value> */
                                case COND_TYPE_IFATTR:
                                key[0] = key_to[0] = '\0';
                                /* parse interface attribute <if>:<value> */
                                case COND_TYPE_IFATTR:
                                key[0] = key_to[0] = '\0';
@@ -1536,6 +1573,7 @@ struct route_ruleset *ruleset_parse(void)
                                case PARAM_TYPE_CALLERIDTYPE:
                                case PARAM_TYPE_CAPABILITY:
                                case PARAM_TYPE_BMODE:
                                case PARAM_TYPE_CALLERIDTYPE:
                                case PARAM_TYPE_CAPABILITY:
                                case PARAM_TYPE_BMODE:
+                               case PARAM_TYPE_HLC:
                                case PARAM_TYPE_DIVERSION:
                                case PARAM_TYPE_DESTIN:
                                case PARAM_TYPE_TYPE:
                                case PARAM_TYPE_DIVERSION:
                                case PARAM_TYPE_DESTIN:
                                case PARAM_TYPE_TYPE:
@@ -1627,6 +1665,67 @@ struct route_ruleset *ruleset_parse(void)
                                        SPRINT(failure, "Bchannel mode '%s' unknown.", key);
                                        goto parse_error;
                                }
                                        SPRINT(failure, "Bchannel mode '%s' unknown.", key);
                                        goto parse_error;
                                }
+                               if (param_defs[index].type == PARAM_TYPE_HLC) {
+                                       param->value_type = VALUE_TYPE_INTEGER;
+                                       if (!strcasecmp(key, "telephony")) {
+                                               param->integer_value = INFO_HLC_TELEPHONY;
+                                               break;
+                                       }
+                                       if (!strcasecmp(key, "faxg2g3")) {
+                                               param->integer_value = INFO_HLC_FAXG2G3;
+                                               break;
+                                       }
+                                       if (!strcasecmp(key, "faxg4")) {
+                                               param->integer_value = INFO_HLC_FAXG4;
+                                               break;
+                                       }
+                                       if (!strcasecmp(key, "teletex1")) {
+                                               param->integer_value = INFO_HLC_TELETEX1;
+                                               break;
+                                       }
+                                       if (!strcasecmp(key, "teletex2")) {
+                                               param->integer_value = INFO_HLC_TELETEX2;
+                                               break;
+                                       }
+                                       if (!strcasecmp(key, "teletex3")) {
+                                               param->integer_value = INFO_HLC_TELETEX3;
+                                               break;
+                                       }
+                                       if (!strcasecmp(key, "videotex1")) {
+                                               param->integer_value = INFO_HLC_VIDEOTEX1;
+                                               break;
+                                       }
+                                       if (!strcasecmp(key, "videotex2")) {
+                                               param->integer_value = INFO_HLC_VIDEOTEX2;
+                                               break;
+                                       }
+                                       if (!strcasecmp(key, "telex")) {
+                                               param->integer_value = INFO_HLC_TELEX;
+                                               break;
+                                       }
+                                       if (!strcasecmp(key, "mhs")) {
+                                               param->integer_value = INFO_HLC_MHS;
+                                               break;
+                                       }
+                                       if (!strcasecmp(key, "osi")) {
+                                               param->integer_value = INFO_HLC_OSI;
+                                               break;
+                                       }
+                                       if (!strcasecmp(key, "maintenance")) {
+                                               param->integer_value = INFO_HLC_MAINTENANCE;
+                                               break;
+                                       }
+                                       if (!strcasecmp(key, "management")) {
+                                               param->integer_value = INFO_HLC_MANAGEMENT;
+                                               break;
+                                       }
+                                       if (!strcasecmp(key, "audiovisual")) {
+                                               param->integer_value = INFO_HLC_AUDIOVISUAL;
+                                               break;
+                                       }
+                                       SPRINT(failure, "HLC type '%s' unknown.", key);
+                                       goto parse_error;
+                               }
                                if (param_defs[index].type == PARAM_TYPE_DIVERSION) {
                                        param->value_type = VALUE_TYPE_INTEGER;
                                        if (!strcasecmp(key, "cfu")) {
                                if (param_defs[index].type == PARAM_TYPE_DIVERSION) {
                                        param->value_type = VALUE_TYPE_INTEGER;
                                        if (!strcasecmp(key, "cfu")) {
diff --git a/route.h b/route.h
index dca5a4e..1606410 100644 (file)
--- a/route.h
+++ b/route.h
@@ -32,6 +32,7 @@ enum { /* how to parse text file during startup */
        COND_TYPE_IP,
        COND_TYPE_CAPABILITY,
        COND_TYPE_BMODE,
        COND_TYPE_IP,
        COND_TYPE_CAPABILITY,
        COND_TYPE_BMODE,
+       COND_TYPE_HLC,
        COND_TYPE_IFATTR,
 };
 
        COND_TYPE_IFATTR,
 };
 
@@ -84,6 +85,7 @@ enum { /* how to parse text file during startup */
        PARAM_TYPE_YESNO,
        PARAM_TYPE_CAPABILITY,
        PARAM_TYPE_BMODE,
        PARAM_TYPE_YESNO,
        PARAM_TYPE_CAPABILITY,
        PARAM_TYPE_BMODE,
+       PARAM_TYPE_HLC,
        PARAM_TYPE_DIVERSION,
        PARAM_TYPE_DESTIN,
        PARAM_TYPE_PORTS,
        PARAM_TYPE_DIVERSION,
        PARAM_TYPE_DESTIN,
        PARAM_TYPE_PORTS,