added timer for recovering missing activation/deactivation replies of bchannels from...
authorSuper User <root@isdn.jolly.ten>
Sat, 16 Feb 2008 08:09:35 +0000 (09:09 +0100)
committerSuper User <root@isdn.jolly.ten>
Sat, 16 Feb 2008 08:09:35 +0000 (09:09 +0100)
this recovers 'hang' of bchannel if the reply message got lost due to buffer overflows

fixed some minor warnings

modified:   Makefile
modified:   README
modified:   action_efi.cpp
modified:   apppbx.cpp
modified:   dss1.cpp
modified:   interface.c
modified:   mISDN.cpp
modified:   mISDN.h
modified:   message.h

Makefile
README
action_efi.cpp
apppbx.cpp
dss1.cpp
interface.c
mISDN.cpp
mISDN.h
message.h

index c19a500..a5dd458 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -29,6 +29,7 @@ PP = g++
 WIZZARD = ./wizzard
 LCR = ./lcr
 LCRADMIN = ./lcradmin
+CFLAGS_LCRADMIN = -DINSTALL_DATA=\"$(INSTALL_DATA)\"
 ifdef WITH-ASTERISK
 CHAN_LCR = ./chan_lcr
 endif
@@ -37,7 +38,7 @@ GEN = ./gentones
 GENW = ./genwave
 GENRC = ./genrc
 GENEXT = ./genextension
-CFLAGS = -DINSTALL_DATA=\"$(INSTALL_DATA)\" -I/usr/include/mISDNuser/
+CFLAGS = -Wall -g -DINSTALL_DATA=\"$(INSTALL_DATA)\" -I/usr/include/mISDNuser/
 #CFLAGS = -Wall -g -DINSTALL_DATA=\"$(INSTALL_DATA)\"
 ifdef WITH-CRYPTO
 CFLAGS += -DCRYPTO
@@ -219,7 +220,7 @@ $(LCR): main.o \
        $(LIBS) -o $(LCR) 
 
 $(LCRADMIN): lcradmin.c cause.c *.h Makefile
-       $(PP) $(LIBDIR) $(CFLAGS) $(CURSES) -lm lcradmin.c cause.c \
+       $(PP) $(LIBDIR) $(CFLAGS_LCRADMIN) $(CURSES) -lm lcradmin.c cause.c \
        -o $(LCRADMIN) 
 
 $(CHAN_LCR): chan_lcr.o bchannel.o
diff --git a/README b/README
index f3bc498..a16ea7c 100644 (file)
--- a/README
+++ b/README
@@ -419,4 +419,5 @@ Changes in Version 0.4
 Changes in Version 0.5
 - Preperations for Asterisk channel driver (chan_lcr)
 - Errors in information elements are now reported inside log/trace.
+- Recover bchannel (de-)activation if message from mISDN got lost
 
index f22cf8a..45a8119 100644 (file)
@@ -70,8 +70,8 @@ void EndpointAppPBX::efi_message_eof(void)
 {
 //     char buffer[32];
        char digit[] = "number_00";
-       struct message          *message;
-       struct port_list        *portlist = ea_endpoint->ep_portlist;
+//     struct message          *message;
+//     struct port_list        *portlist = ea_endpoint->ep_portlist;
 
        PDEBUG(DEBUG_EPOINT, "EPOINT(%d) terminal %s end of file during state: %d\n", ea_endpoint->ep_serial, e_ext.number, e_vbox_state);
 
index 66aba31..243e4dd 100644 (file)
@@ -3120,7 +3120,7 @@ void EndpointAppPBX::join_disconnect_release(int message_type, union parameter *
 void EndpointAppPBX::join_setup(struct port_list *portlist, int message_type, union parameter *param)
 {
        struct message *message;
-       struct interface        *interface;
+//     struct interface        *interface;
 
        /* if we already in setup state, we just update the dialing with new digits */
        if (e_state == EPOINT_STATE_OUT_SETUP
index 7021860..ead7b56 100644 (file)
--- a/dss1.cpp
+++ b/dss1.cpp
@@ -1917,7 +1917,7 @@ void Pdss1::message_isdn(unsigned long prim, unsigned long dinfo, void *data)
 
 void Pdss1::new_state(int state)
 {
-       class Endpoint *epoint;
+//     class Endpoint *epoint;
 
        /* set timeout */
        if (state == PORT_STATE_IN_OVERLAP)
index a77a30d..cad3c32 100644 (file)
@@ -437,8 +437,8 @@ static int inter_channel_in(struct interface *interface, char *filename, int lin
 static int inter_timeouts(struct interface *interface, char *filename, int line, char *parameter, char *value)
 {
        struct interface_port *ifport;
-       struct select_channel *selchannel, **selchannelp;
-       int val;
+//     struct select_channel *selchannel, **selchannelp;
+//     int val;
        char *p, *el;
 
        /* port in chain ? */
index 7bdb30d..1583211 100644 (file)
--- a/mISDN.cpp
+++ b/mISDN.cpp
@@ -72,6 +72,10 @@ extern "C" {
 #define ISDN_PID_L4_B_USER 0x440000ff
 #endif
 
+// timeouts if activating/deactivating response from mISDN got lost
+#define B_TIMER_ACTIVATING 1
+#define B_TIMER_DEACTIVATING 1
+
 /* list of mISDN ports */
 struct mISDNport *mISDNport_first;
 
@@ -641,6 +645,8 @@ static void _bchannel_activate(struct mISDNport *mISDNport, int i, int activate)
        /* trace */
        chan_trace_header(mISDNport, mISDNport->b_port[i], activate?(char*)"BCHANNEL activate":(char*)"BCHANNEL deactivate", DIRECTION_OUT);
        add_trace("channel", NULL, "%d", i+1+(i>=15));
+       if (mISDNport->b_timer[i])
+               add_trace("event", NULL, "timeout recovery");
        end_trace();
 }
 
@@ -826,6 +832,7 @@ void bchannel_event(struct mISDNport *mISDNport, int i, int event)
 {
        class PmISDN *b_port = mISDNport->b_port[i];
        int state = mISDNport->b_state[i];
+       double timer = mISDNport->b_timer[i];
        unsigned long p_m_remote_ref = 0;
        unsigned long p_m_remote_id = 0;
        int p_m_tx_gain = 0;
@@ -883,6 +890,7 @@ void bchannel_event(struct mISDNport *mISDNport, int i, int event)
                                {
                                        _bchannel_activate(mISDNport, i, 1);
                                        state = B_STATE_ACTIVATING;
+                                       timer = now_d + B_TIMER_ACTIVATING;
                                }
                        }
                        break;
@@ -947,6 +955,7 @@ void bchannel_event(struct mISDNport *mISDNport, int i, int event)
                        /* bchannel is active, so we deactivate */
                        _bchannel_activate(mISDNport, i, 0);
                        state = B_STATE_DEACTIVATING;
+                       timer = now_d + B_TIMER_DEACTIVATING;
                        break;
 
                        default:
@@ -959,6 +968,7 @@ void bchannel_event(struct mISDNport *mISDNport, int i, int event)
                break;
 
                case B_EVENT_ACTIVATED:
+               timer = 0;
                switch(state)
                {
                        case B_STATE_ACTIVATING:
@@ -972,6 +982,7 @@ void bchannel_event(struct mISDNport *mISDNport, int i, int event)
                                /* bchannel is active, but exported OR not used anymore (or has wrong stack config), so we deactivate */
                                _bchannel_activate(mISDNport, i, 0);
                                state = B_STATE_DEACTIVATING;
+                               timer = now_d + B_TIMER_DEACTIVATING;
                        }
                        break;
 
@@ -1030,6 +1041,7 @@ void bchannel_event(struct mISDNport *mISDNport, int i, int event)
                        /* bchannel is active, so we deactivate */
                        _bchannel_activate(mISDNport, i, 0);
                        state = B_STATE_DEACTIVATING;
+                       timer = now_d + B_TIMER_DEACTIVATING;
                        break;
 
                        case B_STATE_REMOTE:
@@ -1057,6 +1069,7 @@ void bchannel_event(struct mISDNport *mISDNport, int i, int event)
                break;
 
                case B_EVENT_DEACTIVATED:
+               timer = 0;
                switch(state)
                {
                        case B_STATE_IDLE:
@@ -1089,6 +1102,7 @@ void bchannel_event(struct mISDNport *mISDNport, int i, int event)
                                        {
                                                _bchannel_activate(mISDNport, i, 1);
                                                state = B_STATE_ACTIVATING;
+                                               timer = now_d + B_TIMER_ACTIVATING;
                                        }
                                }
                        }
@@ -1129,6 +1143,7 @@ void bchannel_event(struct mISDNport *mISDNport, int i, int event)
                                        {
                                                _bchannel_activate(mISDNport, i, 1);
                                                state = B_STATE_ACTIVATING;
+                                               timer = now_d + B_TIMER_ACTIVATING;
                                        }
                                }
                        }
@@ -1140,11 +1155,35 @@ void bchannel_event(struct mISDNport *mISDNport, int i, int event)
                }
                break;
 
+               case B_EVENT_TIMEOUT:
+               timer = 0;
+               switch(state)
+               {
+                       case B_STATE_IDLE:
+                       /* ignore due to deactivation confirm after unloading */
+                       break;
+
+                       case B_STATE_ACTIVATING:
+                       _bchannel_activate(mISDNport, i, 1);
+                       timer = now_d + B_TIMER_ACTIVATING;
+                       break;
+
+                       case B_STATE_DEACTIVATING:
+                       _bchannel_activate(mISDNport, i, 0);
+                       timer = now_d + B_TIMER_DEACTIVATING;
+                       break;
+
+                       default:
+                       PERROR("Illegal event %d at state %d, please correct.\n", event, state);
+               }
+               break;
+
                default:
                PERROR("Illegal event %d, please correct.\n", event);
        }
 
        mISDNport->b_state[i] = state;
+       mISDNport->b_timer[i] = timer;
 }
 
 
@@ -2053,6 +2092,12 @@ int mISDN_handler(void)
                i = 0;
                while(i < mISDNport->b_num)
                {
+                       /* process timer events for bchannel handling */
+                       if (mISDNport->b_timer[i])
+                       {
+                               if (mISDNport->b_timer[i] <= now_d)
+                                       bchannel_event(mISDNport, i, B_EVENT_TIMEOUT);
+                       }
                        /* handle port of bchannel */
                        isdnport=mISDNport->b_port[i];
                        if (isdnport)
@@ -2214,6 +2259,12 @@ int mISDN_handler(void)
                i = 0;
                while(i < mISDNport->b_num)
                {
+                       /* process timer events for bchannel handling */
+                       if (mISDNport->b_timer[i])
+                       {
+                               if (mISDNport->b_timer[i] <= now_d)
+                                       bchannel_event(mISDNport, i, B_EVENT_TIMEOUT);
+                       }
                        isdnport=mISDNport->b_port[i];
                        if (isdnport)
                        {
diff --git a/mISDN.h b/mISDN.h
index e2d5b57..836947c 100644 (file)
--- a/mISDN.h
+++ b/mISDN.h
@@ -53,6 +53,7 @@ struct mISDNport {
        unsigned long b_addr[128];
 #endif
        int b_state[128]; /* statemachine, 0 = IDLE */
+       double b_timer[128]; /* timer for state machine */
        unsigned long b_remote_id[128]; /* the socket currently exported */
        unsigned long b_remote_ref[128]; /* the ref currently exported */
        int procids[128]; /* keep track of free ids */
index 1abab34..9987fd1 100644 (file)
--- a/message.h
+++ b/message.h
@@ -151,9 +151,9 @@ enum {
        B_EVENT_DEACTIVATED,    /* DL_RELEASE received */
        B_EVENT_EXPORTED,       /* BCHANNEL_ASSIGN received */
        B_EVENT_IMPORTED,       /* BCHANNEL_REMOVE received */
+       B_EVENT_TIMEOUT,        /* timeout for bchannel state */
 };
 
-
 /* call-info structure CALLER */
 struct caller_info {
        char id[32];                    /* id of caller (user number) */