Replaced polling loop for LCR and chan_lcr with select based event loop.
[lcr.git] / bchannel.c
index fd3e33d..9e878fe 100644 (file)
@@ -50,6 +50,7 @@
 #include "message.h"
 #include "lcrsocket.h"
 #include "cause.h"
 #include "message.h"
 #include "lcrsocket.h"
 #include "cause.h"
+#include "select.h"
 #include "bchannel.h"
 #include "chan_lcr.h"
 #include "callerid.h"
 #include "bchannel.h"
 #include "chan_lcr.h"
 #include "callerid.h"
@@ -73,7 +74,7 @@ int bchannel_initialize(void)
 {
        init_af_isdn();
 
 {
        init_af_isdn();
 
-       return(0);
+       return 0;
 }
 
 void bchannel_deinitialize(void)
 }
 
 void bchannel_deinitialize(void)
@@ -123,6 +124,7 @@ static void ph_control_block(int sock, unsigned int c1, void *c2, int c2_len, ch
                CERROR(NULL, NULL, "Failed to send to socket %d\n", sock);
 }
 
                CERROR(NULL, NULL, "Failed to send to socket %d\n", sock);
 }
 
+static int bchannel_handle(struct lcr_fd *fd, unsigned int what, void *instance, int index);
 
 /*
  * create stack
 
 /*
  * create stack
@@ -130,12 +132,11 @@ static void ph_control_block(int sock, unsigned int c1, void *c2, int c2_len, ch
 int bchannel_create(struct bchannel *bchannel, int mode)
 {
        int ret;
 int bchannel_create(struct bchannel *bchannel, int mode)
 {
        int ret;
-       unsigned int on = 1;
        struct sockaddr_mISDN addr;
 
        if (bchannel->b_sock > -1) {
                CERROR(bchannel->call, NULL, "Socket already created for handle 0x%x\n", bchannel->handle);
        struct sockaddr_mISDN addr;
 
        if (bchannel->b_sock > -1) {
                CERROR(bchannel->call, NULL, "Socket already created for handle 0x%x\n", bchannel->handle);
-               return(0);
+               return 0;
        }
 
        /* open socket */
        }
 
        /* open socket */
@@ -160,18 +161,14 @@ int bchannel_create(struct bchannel *bchannel, int mode)
        }
        if (bchannel->b_sock < 0) {
                CERROR(bchannel->call, NULL, "Failed to open bchannel-socket for handle 0x%x with mISDN-DSP layer. Did you load mISDN_dsp.ko?\n", bchannel->handle);
        }
        if (bchannel->b_sock < 0) {
                CERROR(bchannel->call, NULL, "Failed to open bchannel-socket for handle 0x%x with mISDN-DSP layer. Did you load mISDN_dsp.ko?\n", bchannel->handle);
-               return(0);
-       }
-       
-       /* set nonblocking io */
-       ret = ioctl(bchannel->b_sock, FIONBIO, &on);
-       if (ret < 0) {
-               CERROR(bchannel->call, NULL, "Failed to set bchannel-socket handle 0x%x into nonblocking IO\n", bchannel->handle);
-               close(bchannel->b_sock);
-               bchannel->b_sock = -1;
-               return(0);
+               return 0;
        }
 
        }
 
+       /* register fd */
+       memset(&bchannel->lcr_fd, 0, sizeof(bchannel->lcr_fd));
+       bchannel->lcr_fd.fd = bchannel->b_sock;
+       register_fd(&bchannel->lcr_fd, LCR_FD_READ | LCR_FD_EXCEPT, bchannel_handle, bchannel, 0);
+
        /* bind socket to bchannel */
        addr.family = AF_ISDN;
        addr.dev = (bchannel->handle>>8);
        /* bind socket to bchannel */
        addr.family = AF_ISDN;
        addr.dev = (bchannel->handle>>8);
@@ -179,11 +176,12 @@ int bchannel_create(struct bchannel *bchannel, int mode)
        ret = bind(bchannel->b_sock, (struct sockaddr *)&addr, sizeof(addr));
        if (ret < 0) {
                CERROR(bchannel->call, NULL, "Failed to bind bchannel-socket for handle 0x%x with mISDN-DSP layer. (port %d, channel %d) Did you load mISDN_dsp.ko?\n", bchannel->handle, addr.dev, addr.channel);
        ret = bind(bchannel->b_sock, (struct sockaddr *)&addr, sizeof(addr));
        if (ret < 0) {
                CERROR(bchannel->call, NULL, "Failed to bind bchannel-socket for handle 0x%x with mISDN-DSP layer. (port %d, channel %d) Did you load mISDN_dsp.ko?\n", bchannel->handle, addr.dev, addr.channel);
+               unregister_fd(&bchannel->lcr_fd);
                close(bchannel->b_sock);
                bchannel->b_sock = -1;
                close(bchannel->b_sock);
                bchannel->b_sock = -1;
-               return(0);
+               return 0;
        }
        }
-       return(1);
+       return 1;
 }
 
 
 }
 
 
@@ -264,6 +262,7 @@ static void bchannel_activated(struct bchannel *bchannel)
 void bchannel_destroy(struct bchannel *bchannel)
 {
        if (bchannel->b_sock > -1) {
 void bchannel_destroy(struct bchannel *bchannel)
 {
        if (bchannel->b_sock > -1) {
+               unregister_fd(&bchannel->lcr_fd);
                close(bchannel->b_sock);
                bchannel->b_sock = -1;
        }
                close(bchannel->b_sock);
                bchannel->b_sock = -1;
        }
@@ -517,63 +516,54 @@ void bchannel_gain(struct bchannel *bchannel, int gain, int tx)
 /*
  * main loop for processing messages from mISDN
  */
 /*
  * main loop for processing messages from mISDN
  */
-int bchannel_handle(void)
+static int bchannel_handle(struct lcr_fd *fd, unsigned int what, void *instance, int index)
 {
 {
-       int ret, work = 0;
-       struct bchannel *bchannel;
+       struct bchannel *bchannel = (struct bchannel *)instance;
+       int ret;
        unsigned char buffer[2048+MISDN_HEADER_LEN];
        struct mISDNhead *hh = (struct mISDNhead *)buffer;
 
        unsigned char buffer[2048+MISDN_HEADER_LEN];
        struct mISDNhead *hh = (struct mISDNhead *)buffer;
 
-       /* process all bchannels */
-       bchannel = bchannel_first;
-       while(bchannel) {
-               /* handle message from bchannel */
-               if (bchannel->b_sock > -1) {
-                       ret = recv(bchannel->b_sock, buffer, sizeof(buffer), 0);
-                       if (ret >= (int)MISDN_HEADER_LEN) {
-                               work = 1;
-                               switch(hh->prim) {
-                                       /* we don't care about confirms, we use rx data to sync tx */
-                                       case PH_DATA_CNF:
-                                       break;
-
-                                       /* we receive audio data, we respond to it AND we send tones */
-                                       case PH_DATA_IND:
-                                       case PH_DATA_REQ:
-                                       case DL_DATA_IND:
-                                       case PH_CONTROL_IND:
-                                       bchannel_receive(bchannel, buffer, ret-MISDN_HEADER_LEN);
-                                       break;
-
-                                       case PH_ACTIVATE_IND:
-                                       case DL_ESTABLISH_IND:
-                                       case PH_ACTIVATE_CNF:
-                                       case DL_ESTABLISH_CNF:
-                                       CDEBUG(bchannel->call, NULL, "DL_ESTABLISH confirm: bchannel is now activated (socket %d).\n", bchannel->b_sock);
-                                       bchannel_activated(bchannel);
-                                       break;
-
-                                       case PH_DEACTIVATE_IND:
-                                       case DL_RELEASE_IND:
-                                       case PH_DEACTIVATE_CNF:
-                                       case DL_RELEASE_CNF:
-                                       CDEBUG(bchannel->call, NULL, "DL_RELEASE confirm: bchannel is now de-activated (socket %d).\n", bchannel->b_sock);
+       ret = recv(bchannel->b_sock, buffer, sizeof(buffer), 0);
+       if (ret >= (int)MISDN_HEADER_LEN) {
+               switch(hh->prim) {
+                       /* we don't care about confirms, we use rx data to sync tx */
+                       case PH_DATA_CNF:
+                       break;
+
+                       /* we receive audio data, we respond to it AND we send tones */
+                       case PH_DATA_IND:
+                       case PH_DATA_REQ:
+                       case DL_DATA_IND:
+                       case PH_CONTROL_IND:
+                       bchannel_receive(bchannel, buffer, ret-MISDN_HEADER_LEN);
+                       break;
+
+                       case PH_ACTIVATE_IND:
+                       case DL_ESTABLISH_IND:
+                       case PH_ACTIVATE_CNF:
+                       case DL_ESTABLISH_CNF:
+                       CDEBUG(bchannel->call, NULL, "DL_ESTABLISH confirm: bchannel is now activated (socket %d).\n", bchannel->b_sock);
+                       bchannel_activated(bchannel);
+                       break;
+
+                       case PH_DEACTIVATE_IND:
+                       case DL_RELEASE_IND:
+                       case PH_DEACTIVATE_CNF:
+                       case DL_RELEASE_CNF:
+                       CDEBUG(bchannel->call, NULL, "DL_RELEASE confirm: bchannel is now de-activated (socket %d).\n", bchannel->b_sock);
 //                                     bchannel_deactivated(bchannel);
 //                                     bchannel_deactivated(bchannel);
-                                       break;
-
-                                       default:
-                                       CERROR(bchannel->call, NULL, "child message not handled: prim(0x%x) socket(%d) data len(%d)\n", hh->prim, bchannel->b_sock, ret - MISDN_HEADER_LEN);
-                               }
-                       } else {
-                               if (ret < 0 && errno != EWOULDBLOCK)
-                                       CERROR(bchannel->call, NULL, "Read from socket %d failed with return code %d\n", bchannel->b_sock, ret);
-                       }
+                       break;
+
+                       default:
+                       CERROR(bchannel->call, NULL, "child message not handled: prim(0x%x) socket(%d) data len(%d)\n", hh->prim, bchannel->b_sock, ret - MISDN_HEADER_LEN);
                }
                }
-               bchannel = bchannel->next;
+       } else {
+//             if (ret < 0 && errno != EWOULDBLOCK)
+               CERROR(bchannel->call, NULL, "Read from socket %d failed with return code %d\n", bchannel->b_sock, ret);
        }
 
        /* if we received at least one b-frame, we will return 1 */
        }
 
        /* if we received at least one b-frame, we will return 1 */
-       return(work);
+       return 0;
 }
 
 
 }
 
 
@@ -590,7 +580,7 @@ struct bchannel *find_bchannel_handle(unsigned int handle)
                        break;
                bchannel = bchannel->next;
        }
                        break;
                bchannel = bchannel->next;
        }
-       return(bchannel);
+       return bchannel;
 }
 
 #if 0
 }
 
 #if 0
@@ -603,7 +593,7 @@ struct bchannel *find_bchannel_ref(unsigned int ref)
                        break;
                bchannel = bchannel->next;
        }
                        break;
                bchannel = bchannel->next;
        }
-       return(bchannel);
+       return bchannel;
 }
 #endif
 
 }
 #endif
 
@@ -616,12 +606,12 @@ struct bchannel *alloc_bchannel(unsigned int handle)
 
        *bchannelp = (struct bchannel *)calloc(1, sizeof(struct bchannel));
        if (!*bchannelp)
 
        *bchannelp = (struct bchannel *)calloc(1, sizeof(struct bchannel));
        if (!*bchannelp)
-               return(NULL);
+               return NULL;
        (*bchannelp)->handle = handle;
        (*bchannelp)->b_state = BSTATE_IDLE;
        (*bchannelp)->b_sock = -1;
                
        (*bchannelp)->handle = handle;
        (*bchannelp)->b_state = BSTATE_IDLE;
        (*bchannelp)->b_sock = -1;
                
-       return(*bchannelp);
+       return *bchannelp;
 }
 
 void free_bchannel(struct bchannel *bchannel)
 }
 
 void free_bchannel(struct bchannel *bchannel)