chan_lcr hopefully now compiles against SVN version of asterisk.
authorAndreas Eversberg <andreas@eversberg.eu>
Sun, 15 Feb 2009 08:04:14 +0000 (09:04 +0100)
committerAndreas Eversberg <andreas@eversberg.eu>
Sun, 15 Feb 2009 08:04:14 +0000 (09:04 +0100)
Added limitation option for maximum dialed digits. If dial string exceeds
that limit, overlap-dialing is used to complete dial string.
Siemens EWSD (APS V16) only allows 20 digits at a time.

modified:   README
modified:   chan_lcr.c
modified:   default/interface.conf
modified:   dss1.cpp
modified:   dss1.h
modified:   ie.cpp
modified:   interface.c
modified:   interface.h

README
chan_lcr.c
default/interface.conf
dss1.cpp
dss1.h
ie.cpp
interface.c
interface.h

diff --git a/README b/README
index 0bf0618..da23ec5 100644 (file)
--- a/README
+++ b/README
@@ -454,8 +454,14 @@ Changes in Version 1.2
 - Introduceing autoconf (./configure) with help of Joerg and Peter.
   -> Default installation path remains /usr/local/lcr, so don't worry!
 
-Fixes in current Version
+Changes in Version 1.3
 - Finished autoconf.
 - Obsolete "pbxwatch" is removed. 
+- fixes in chan_lcr, thanx to peter and gregor
+- message pointer forwarding fix, thanx to bodo!
+- capability fix, thanx to gregor
+- processing of second caller id
+- Dialing length can now be limited. EWSD allows only 20 digits at a time.
+  -> Multiple messages are sent to dial full string.
 
 
index f6ff27c..c1d3745 100644 (file)
@@ -1995,7 +1995,7 @@ static int lcr_write(struct ast_channel *ast, struct ast_frame *f)
                return -1;
        }
        if (call->bchannel && f->samples)
-               bchannel_transmit(call->bchannel, f->data, f->samples);
+               bchannel_transmit(call->bchannel, (unsigned char *)f->data, f->samples);
        ast_mutex_unlock(&chan_lock);
        return 0;
 }
@@ -2035,7 +2035,7 @@ static struct ast_frame *lcr_read(struct ast_channel *ast)
        call->read_fr.datalen = len;
        call->read_fr.samples = len;
        call->read_fr.delivery = ast_tv(0,0);
-       call->read_fr.data = call->read_buff;
+       (unsigned char *)call->read_fr.data = call->read_buff;
        ast_mutex_unlock(&chan_lock);
 
        return &call->read_fr;
index 5ee81be..51cc036 100644 (file)
 #nt
 
 
+# The remote switch may reject extreamly large numbers to be dialed during
+# setup message. Define a limit of maximum numbers to dial. The rest of
+# digits will be dialed after setup via overlap dialing.
+
+#[Ext]
+#portnum 0
+#dialmax 20
+
 # Hint: Enter "lcr interface" for quick help on interface options.
 
 
index 3b14332..707cfc2 100644 (file)
--- a/dss1.cpp
+++ b/dss1.cpp
@@ -30,7 +30,7 @@ Pdss1::Pdss1(int type, struct mISDNport *mISDNport, char *portname, struct port_
        p_m_d_tespecial = mISDNport->tespecial;
        p_m_d_l3id = 0;
        p_m_d_ces = -1;
-       p_m_d_queue = NULL;
+       p_m_d_queue[0] = '\0';
        p_m_d_notify_pending = NULL;
        p_m_d_collect_cause = 0;
        p_m_d_collect_location = 0;
@@ -45,9 +45,6 @@ Pdss1::Pdss1(int type, struct mISDNport *mISDNport, char *portname, struct port_
 Pdss1::~Pdss1()
 {
        /* remove queued message */
-       if (p_m_d_queue)
-               message_free(p_m_d_queue);
-
        if (p_m_d_notify_pending)
                message_free(p_m_d_notify_pending);
 }
@@ -821,6 +818,9 @@ void Pdss1::setup_acknowledge_ind(unsigned int cmd, unsigned int pid, struct l3_
        int coding, location, progress;
        int ret;
        struct lcr_msg *message;
+       int max = p_m_mISDNport->ifport->dialmax;
+       char *number;
+       l3_msg *nl3m;
 
        l1l2l3_trace_header(p_m_mISDNport, this, L3_SETUP_ACKNOWLEDGE_IND, DIRECTION_IN);
        dec_ie_channel_id(l3m, &exclusive, &channel);
@@ -844,6 +844,21 @@ void Pdss1::setup_acknowledge_ind(unsigned int cmd, unsigned int pid, struct l3_
        message_put(message);
 
        new_state(PORT_STATE_OUT_OVERLAP);
+
+       number = p_m_d_queue;
+       while (number[0]) /* as long we have something to dial */
+       {
+               if (max > strlen(number) || max == 0)
+                       max = strlen(number);
+      
+               nl3m = create_l3msg();
+               l1l2l3_trace_header(p_m_mISDNport, this, L3_INFORMATION_REQ, DIRECTION_OUT);
+               enc_ie_called_pn(nl3m, 0, 1, (unsigned char *)number, max);
+               end_trace();
+               p_m_mISDNport->ml3->to_layer3(p_m_mISDNport->ml3, MT_INFORMATION, p_m_d_l3id, nl3m);
+               number += max;
+       }
+       p_m_d_queue[0] = '\0';
 }
 
 /* CC_PROCEEDING INDICATION */
@@ -1927,16 +1942,25 @@ int Pdss1::handler(void)
 void Pdss1::message_information(unsigned int epoint_id, int message_id, union parameter *param)
 {
        l3_msg *l3m;
+       char *display = param->information.display;
+       char *number = param->information.id;
+       int max = p_m_mISDNport->ifport->dialmax;
 
-       if (param->information.id[0]) /* only if we have something to dial */
+       while (number[0]) /* as long we have something to dial */
        {
+               if (max > strlen(number) || max == 0)
+                       max = strlen(number);
+      
                l3m = create_l3msg();
                l1l2l3_trace_header(p_m_mISDNport, this, L3_INFORMATION_REQ, DIRECTION_OUT);
-               enc_ie_called_pn(l3m, 0, 1, (unsigned char *)param->information.id);
-               if (p_m_d_ntmode || p_m_d_tespecial)
-                       enc_ie_display(l3m, (unsigned char *)param->information.display);
+               enc_ie_called_pn(l3m, 0, 1, (unsigned char *)number, max);
+               if ((p_m_d_ntmode || p_m_d_tespecial) && display[0]) {
+                       enc_ie_display(l3m, (unsigned char *)display);
+                       display = "";
+               }
                end_trace();
                p_m_mISDNport->ml3->to_layer3(p_m_mISDNport->ml3, MT_INFORMATION, p_m_d_l3id, l3m);
+               number += max;
        }
        new_state(p_state);
 }
@@ -1954,6 +1978,7 @@ void Pdss1::message_setup(unsigned int epoint_id, int message_id, union paramete
        int capability, mode, rate, coding, user, presentation, interpretation, hlc, exthlc;
        int channel, exclusive;
        struct epoint_list *epointlist;
+       int max = p_m_mISDNport->ifport->dialmax;
 
        /* release if port is blocked */
        if (p_m_mISDNport->ifport->block)
@@ -2140,7 +2165,10 @@ void Pdss1::message_setup(unsigned int epoint_id, int message_id, union paramete
        /* dialing information */
        if (p_dialinginfo.id[0]) /* only if we have something to dial */
        {
-               enc_ie_called_pn(l3m, 0, 1, (unsigned char *)p_dialinginfo.id);
+               if (max > strlen(p_dialinginfo.id) || max == 0)
+                       max = strlen(p_dialinginfo.id);
+               enc_ie_called_pn(l3m, 0, 1, (unsigned char *)p_dialinginfo.id, max);
+               SCPY(p_m_d_queue, p_dialinginfo.id + max);
        }
        /* sending complete */
        if (p_dialinginfo.sending_complete)
@@ -3028,56 +3056,6 @@ int stack2manager(struct mISDNport *mISDNport, unsigned int cmd, unsigned int pi
 }
 
 
-#if 0
-/*
- * sending message that were queued during L1 activation
- * or releasing port if link is down
- */
-void setup_queue(struct mISDNport *mISDNport, int link)
-{
-       class Port *port;
-       class Pdss1 *pdss1;
-       struct lcr_msg *message;
-
-       if (!mISDNport->ntmode)
-               return;
-
-       /* check all port objects for pending message */
-       port = port_first;
-       while(port)
-       {
-               if ((port->p_type&PORT_CLASS_mISDN_MASK) == PORT_CLASS_mISDN_DSS1)
-               {
-                       pdss1 = (class Pdss1 *)port;
-                       if (pdss1->p_m_mISDNport == mISDNport)
-                       {
-                               if (pdss1->p_m_d_queue)
-                               {
-                                       if (link)
-                                       {
-                                               PDEBUG(DEBUG_ISDN, "the L1 became active, so we send queued message for portnum=%d (%s).\n", mISDNport->portnum, pdss1->p_name);
-                                               /* LAYER 1 is up, so we send */
-                                               pdss1->message_setup(pdss1->p_m_d_queue->id_from, pdss1->p_m_d_queue->type, &pdss1->p_m_d_queue->param);
-                                               message_free(pdss1->p_m_d_queue);
-                                               pdss1->p_m_d_queue = NULL;
-                                       } else
-                                       {
-                                               PDEBUG(DEBUG_ISDN, "the L1 became NOT active, so we release port for portnum=%d (%s).\n", mISDNport->portnum, pdss1->p_name);
-                                               message = message_create(pdss1->p_serial, pdss1->p_m_d_queue->id_from, PORT_TO_EPOINT, MESSAGE_RELEASE);
-                                               message->param.disconnectinfo.cause = 27;
-                                               message->param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
-                                               message_put(message);
-                                               pdss1->new_state(PORT_STATE_RELEASE);
-                                               pdss1->p_m_delete = 1;
-                                       }
-                               }
-                       }
-               }
-               port = port->next;
-       }
-}
-
-#endif
 
 
 
diff --git a/dss1.h b/dss1.h
index cb31b3b..168a56b 100644 (file)
--- a/dss1.h
+++ b/dss1.h
@@ -23,7 +23,7 @@ class Pdss1 : public PmISDN
 
        int p_m_d_ntmode;                       /* flags the nt-mode */
        int p_m_d_tespecial;                    /* special te-mode with all nt-mode IEs */
-       struct lcr_msg *p_m_d_queue;            /* queue for SETUP if link is down */
+       char p_m_d_queue[64];                   /* queue for dialing information (if larger than setup allows) */
        struct lcr_msg *p_m_d_notify_pending;   /* queue for NOTIFY if not connected */
 
        int p_m_d_collect_cause;                /* collecting cause and location */
@@ -69,7 +69,7 @@ class Pdss1 : public PmISDN
        void dec_ie_bearer(struct l3_msg *l3m, int *coding, int *capability, int *mode, int *rate, int *multi, int *user);
        void enc_ie_call_id(struct l3_msg *l3m, unsigned char *callid, int callid_len);
        void dec_ie_call_id(struct l3_msg *l3m, unsigned char *callid, int *callid_len);
-       void enc_ie_called_pn(struct l3_msg *l3m, int type, int plan, unsigned char *number);
+       void enc_ie_called_pn(struct l3_msg *l3m, int type, int plan, unsigned char *number, int number_len);
        void dec_ie_called_pn(struct l3_msg *l3m, int *type, int *plan, unsigned char *number, int number_len);
        void enc_ie_calling_pn(struct l3_msg *l3m, int type, int plan, int present, int screen, unsigned char *number, int type2, int plan2, int present2, int screen2, unsigned char *number2);
        void dec_ie_calling_pn(struct l3_msg *l3m, int *type, int *plan, int *present, int *screen, unsigned char *number, int number_len, int *type2, int *plan2, int *present2, int *screen2, unsigned char *number2, int number_len2);
diff --git a/ie.cpp b/ie.cpp
index c4033c4..1e18b77 100644 (file)
--- a/ie.cpp
+++ b/ie.cpp
@@ -314,7 +314,7 @@ void Pdss1::dec_ie_call_id(struct l3_msg *l3m, unsigned char *callid, int *calli
 
 
 /* IE_CALLED_PN */
-void Pdss1::enc_ie_called_pn(struct l3_msg *l3m, int type, int plan, unsigned char *number)
+void Pdss1::enc_ie_called_pn(struct l3_msg *l3m, int type, int plan, unsigned char *number, int number_len)
 {
        unsigned char p[256];
        int l;
@@ -337,13 +337,15 @@ void Pdss1::enc_ie_called_pn(struct l3_msg *l3m, int type, int plan, unsigned ch
 
        add_trace("called_pn", "type", "%d", type);
        add_trace("called_pn", "plan", "%d", plan);
-       add_trace("called_pn", "number", "%s", number);
+       UNCPY((char *)p, (char *)number, number_len);
+       p[number_len] = '\0';
+       add_trace("called_pn", "number", "%s", p);
 
-       l = 1+strlen((char *)number);
+       l = 1+number_len;
        p[0] = IE_CALLED_PN;
        p[1] = l;
        p[2] = 0x80 + (type<<4) + plan;
-       UNCPY((char *)p+3, (char *)number, strlen((char *)number));
+       UNCPY((char *)p+3, (char *)number, number_len);
        add_layer3_ie(l3m, p[0], p[1], p+2);
 }
 
index 5549654..1e4bc66 100644 (file)
@@ -898,6 +898,23 @@ static int inter_filter(struct interface *interface, char *filename, int line, c
        }
        return(0);
 }
+static int inter_dialmax(struct interface *interface, char *filename, int line, char *parameter, char *value)
+{
+       struct interface_port *ifport;
+
+       /* port in chain ? */
+       if (!interface->ifport)
+       {
+               SPRINT(interface_error, "Error in %s (line %d): parameter '%s' expects previous 'port' definition.\n", filename, line, parameter);
+               return(-1);
+       }
+       /* goto end of chain */
+       ifport = interface->ifport;
+       while(ifport->next)
+               ifport = ifport->next;
+       ifport->dialmax = atoi(value);
+       return(0);
+}
 
 
 /*
@@ -1008,6 +1025,9 @@ struct interface_param interface_param[] = {
        "pipeline <string> - Sets echo cancelation pipeline.\n"
        "blowfish <key> - Adds encryption. Key must be 4-56 bytes (8-112 hex characters."},
 
+       {"dialmax", &inter_dialmax, "<digits>",
+       "Limits the number of digits in setup/information message."},
+
        {NULL, NULL, NULL, NULL}
 };
 
index 09e0778..46671a4 100644 (file)
@@ -62,6 +62,7 @@ struct interface_port {
         int                    tout_disconnect;
 //     int                     tout_hold;
 //     int                     tout_park;
+       int                     dialmax; /* maximum number of digits to dial */
 };
 
 struct interface_msn {