socket api work
[lcr.git] / mISDN.cpp
index 7bdb30d..75cdadf 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;
 
@@ -92,18 +96,19 @@ int mISDN_initialize(void)
                return(-1);
        }
 
-       /* initialize stuff of the NT lib */
+       /* open debug, if enabled and not only stack debugging */
+       if (options.deb && (options.deb != DEBUG_STACK))
+       {
+               SPRINT(debug_log, "%s/debug.log", INSTALL_DATA);
+               debug_fp = fopen(debug_log, "a");
+       }
+
        if (options.deb & DEBUG_STACK)
        {
-               global_debug = 0xffffffff & ~DBGM_MSG;
-//             global_debug = DBGM_L3DATA;
+               SPRINT(debug_stack, "%s/debug_mISDN.log", INSTALL_DATA);
+               mISDN_debug_init(DBGM_ALL, debug_stack, debug_stack, debug_stack);
        } else
-               global_debug = DBGM_MAN;
-       SPRINT(debug_log, "%s/debug.log", INSTALL_DATA);
-       if (options.deb & DEBUG_LOG)
-               mISDN_debug_init(global_debug, debug_log, debug_log, debug_log);
-       else
-               mISDN_debug_init(global_debug, NULL, NULL, NULL);
+               mISDN_debug_init(0, NULL, NULL, NULL);
 
        /* init mlayer3 */
        init_layer3(4); // buffer of 4
@@ -117,6 +122,10 @@ void mISDN_deinitialize(void)
 
        mISDN_debug_close();
 
+       if (debug_fp)
+               fclose(debug_fp);
+       debug_fp = NULL;
+
        if (mISDNsocket > -1)
                close(mISDNsocket);
 }
@@ -178,6 +187,7 @@ void mISDN_deinitialize(void)
        unsigned char buff[1025];
 
        debug_close();
+       global_debug = 0;
 
        if (mISDNdevice >= 0)
        {
@@ -641,6 +651,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 +838,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 +896,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 +961,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 +974,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 +988,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 +1047,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 +1075,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 +1108,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 +1149,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 +1161,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 +2098,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 +2265,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)
                        {
@@ -2422,6 +2479,15 @@ int mISDN_handler(void)
        if (!mISDNport)
        {
                PERROR("message belongs to no mISDNport: prim(0x%x) addr(0x%x) msg->len(%d)\n", frm->prim, frm->addr, msg->len);
+               // show a list of all mISDNports and their address
+#if 0
+               mISDNport = mISDNport_first;
+               while(mISDNport)
+               {
+                       PERROR(" port %s  %x -> %x\n", mISDNport->name, (frm->addr&MASTER_ID_MASK), (unsigned int)(mISDNport->upper_id&MASTER_ID_MASK));
+                       mISDNport = mISDNport->next;
+               } 
+#endif
                goto out;
        }