]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
cache sockets to wanpipe channels
authorAnthony Minessale <anthony.minessale@gmail.com>
Sun, 24 Sep 2006 15:25:36 +0000 (15:25 +0000)
committerAnthony Minessale <anthony.minessale@gmail.com>
Sun, 24 Sep 2006 15:25:36 +0000 (15:25 +0000)
git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@2822 d0543943-73ff-0310-b7d9-9358b9ac24b2

src/mod/endpoints/mod_wanpipe/mod_wanpipe.c

index accddffd9c111d5440ed43b00fe7fd89d1d7a806..6c9f14d29351c13b627750bc75cc51f8fb35df8d 100644 (file)
@@ -77,6 +77,8 @@ static struct {
        int supress_dtmf_tone;
        int configured_spans;
        char *dialplan;
+       switch_hash_t *call_hash;
+       switch_mutex_t *hash_mutex;
 } globals;
 
 struct wanpipe_pri_span {
@@ -92,6 +94,15 @@ struct wanpipe_pri_span {
        struct sangoma_pri spri;
 };
 
+struct wpsock {
+       int fd;
+       char *name;
+       struct private_object *tech_pvt;
+};
+
+typedef struct wpsock wpsock_t;
+
+
 #define MAX_SPANS 128
 static struct wanpipe_pri_span *SPANS[MAX_SPANS];
 
@@ -106,7 +117,7 @@ struct private_object {
        struct sangoma_pri *spri;
        sangoma_api_hdr_t hdrframe;
        switch_caller_profile_t *caller_profile;
-       int socket;
+       wpsock_t *wpsock;
        int callno;
        int span;
        int cause;
@@ -127,6 +138,83 @@ struct channel_map {
        switch_core_session_t *map[36];
 };
 
+static int wp_close(struct private_object *tech_pvt)
+{
+       int ret = 0;
+
+       switch_mutex_lock(globals.hash_mutex);
+       if (tech_pvt->wpsock && tech_pvt->wpsock->tech_pvt == tech_pvt) {
+               tech_pvt->wpsock->tech_pvt = NULL;
+               ret = 1;
+       }
+       switch_mutex_unlock(globals.hash_mutex);
+       
+       return ret;
+}
+
+static int wp_open(struct private_object *tech_pvt, int span, int chan)
+{
+       int fd;
+       wpsock_t *sock;
+       char name[25];
+       
+       snprintf(name, sizeof(name), "s%dc%d", span, chan);
+
+       switch_mutex_lock(globals.hash_mutex);
+       if ((sock = switch_core_hash_find(globals.call_hash, name))) {
+               fd = sock->fd;
+       } else {
+               if ((fd = sangoma_open_tdmapi_span_chan(span, chan)) > -1) {
+                       if ((sock = malloc(sizeof(*sock)))) {
+                               memset(sock, 0, sizeof(*sock));
+                               sock->fd = fd;
+                               sock->name = strdup(name);
+                               switch_core_hash_insert(globals.call_hash, sock->name, sock);
+                       }
+               }
+       }
+
+       if (sock) {
+               if (sock->tech_pvt) {
+                       if (tech_pvt->session) {
+                               switch_channel_t *channel = switch_core_session_get_channel(tech_pvt->session);
+                               switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
+                       }
+               }
+               sock->tech_pvt = tech_pvt;
+               tech_pvt->wpsock = sock;
+       }
+
+       switch_mutex_unlock(globals.hash_mutex);
+
+       return sock ? 1 : 0;
+}
+
+static int wp_restart(int span, int chan)
+{
+       wpsock_t *sock;
+       int fd;
+       char name[25];
+       
+       snprintf(name, sizeof(name), "s%dc%d", span, chan);
+
+       switch_mutex_lock(globals.hash_mutex);
+       if ((sock = switch_core_hash_find(globals.call_hash, name))) {
+               switch_core_hash_delete(globals.call_hash, sock->name);
+               fd = sock->fd;
+       } else {
+               fd = sangoma_open_tdmapi_span_chan(span, chan);
+       }
+       switch_mutex_unlock(globals.hash_mutex);
+
+       if (fd > -1) {
+               close(fd);
+               return 0;
+       }
+       
+       return -1;
+}
+
 
 static void set_global_dialplan(char *dialplan)
 {
@@ -240,15 +328,15 @@ static switch_status_t wanpipe_on_init(switch_core_session_t *session)
 
        tech_pvt->read_frame.data = tech_pvt->databuf;
 
-       err = sangoma_tdm_set_codec(tech_pvt->socket, &tdm_api, WP_SLINEAR);
+       err = sangoma_tdm_set_codec(tech_pvt->wpsock->fd, &tdm_api, WP_SLINEAR);
        
-       mtu_mru = sangoma_tdm_get_usr_mtu_mru(tech_pvt->socket, &tdm_api);      
+       mtu_mru = sangoma_tdm_get_usr_mtu_mru(tech_pvt->wpsock->fd, &tdm_api);  
        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "WANPIPE INIT MTU is %d\n", mtu_mru);
 
        if (mtu_mru != globals.mtu) {
-               sangoma_tdm_set_usr_period(tech_pvt->socket, &tdm_api, 40);
-               err = sangoma_tdm_set_usr_period(tech_pvt->socket, &tdm_api, new_mtu);
-               mtu_mru = sangoma_tdm_get_usr_mtu_mru(tech_pvt->socket, &tdm_api);
+               sangoma_tdm_set_usr_period(tech_pvt->wpsock->fd, &tdm_api, 40);
+               err = sangoma_tdm_set_usr_period(tech_pvt->wpsock->fd, &tdm_api, new_mtu);
+               mtu_mru = sangoma_tdm_get_usr_mtu_mru(tech_pvt->wpsock->fd, &tdm_api);
                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "ADJUSTED MTU AFTER SETTING IT TO %d is %d %d [%s]\n", new_mtu, mtu_mru, err, strerror(err));
                if (mtu_mru != globals.mtu) {
                        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failure to adjust MTU\n");
@@ -344,7 +432,8 @@ static switch_status_t wanpipe_on_hangup(switch_core_session_t *session)
                chanmap = tech_pvt->spri->private_info;
        }
 
-       sangoma_socket_close(&tech_pvt->socket);
+       //sangoma_socket_close(&tech_pvt->wpsock->fd);
+       wp_close(tech_pvt);
 
        switch_core_codec_destroy(&tech_pvt->read_codec);
        switch_core_codec_destroy(&tech_pvt->write_codec);
@@ -434,7 +523,7 @@ static switch_status_t wanpipe_read_frame(switch_core_session_t *session, switch
        assert(tech_pvt != NULL);
 
 
-       if (switch_test_flag(tech_pvt, TFLAG_BYE) || tech_pvt->socket < 0) {
+       if (switch_test_flag(tech_pvt, TFLAG_BYE) || tech_pvt->wpsock->fd < 0) {
                return SWITCH_STATUS_GENERR;
        }
 
@@ -444,16 +533,16 @@ static switch_status_t wanpipe_read_frame(switch_core_session_t *session, switch
        memset(tech_pvt->databuf, 0, sizeof(tech_pvt->databuf));
        while (bytes < globals.mtu) {
 
-               if (switch_test_flag(tech_pvt, TFLAG_BYE) || tech_pvt->socket < 0) {
+               if (switch_test_flag(tech_pvt, TFLAG_BYE) || tech_pvt->wpsock->fd < 0) {
                        return SWITCH_STATUS_GENERR;
                }
 
 
-               if (sangoma_socket_waitfor(tech_pvt->socket, 1000, POLLIN | POLLERR | POLLHUP) <= 0) {
+               if (sangoma_socket_waitfor(tech_pvt->wpsock->fd, 1000, POLLIN | POLLERR | POLLHUP) <= 0) {
                        return SWITCH_STATUS_GENERR;
                }
 
-               if ((res = sangoma_readmsg_socket(tech_pvt->socket,
+               if ((res = sangoma_readmsg_socket(tech_pvt->wpsock->fd,
                                                                                  &tech_pvt->hdrframe,
                                                                                  sizeof(tech_pvt->hdrframe), bp, sizeof(tech_pvt->databuf) - bytes, 0)) < 0) {
                        if (errno == EBUSY) {
@@ -467,7 +556,7 @@ static switch_status_t wanpipe_read_frame(switch_core_session_t *session, switch
                bp += bytes;
        }
 
-       if (!bytes || switch_test_flag(tech_pvt, TFLAG_BYE) || tech_pvt->socket < 0) {
+       if (!bytes || switch_test_flag(tech_pvt, TFLAG_BYE) || tech_pvt->wpsock->fd < 0) {
                return SWITCH_STATUS_GENERR;
        }
 
@@ -520,7 +609,7 @@ static switch_status_t wanpipe_write_frame(switch_core_session_t *session, switc
 
 
        while (tech_pvt->dtmf_buffer && bwrote < frame->datalen && bytes > 0 && switch_buffer_inuse(tech_pvt->dtmf_buffer) > 0) {
-               if (switch_test_flag(tech_pvt, TFLAG_BYE) || tech_pvt->socket < 0) {
+               if (switch_test_flag(tech_pvt, TFLAG_BYE) || tech_pvt->wpsock->fd < 0) {
                        return SWITCH_STATUS_GENERR;
                }
 
@@ -530,14 +619,14 @@ static switch_status_t wanpipe_write_frame(switch_core_session_t *session, switc
                        }
                }
 
-               if (sangoma_socket_waitfor(tech_pvt->socket, 1000, POLLOUT | POLLERR | POLLHUP) <= 0) {
+               if (sangoma_socket_waitfor(tech_pvt->wpsock->fd, 1000, POLLOUT | POLLERR | POLLHUP) <= 0) {
                        return SWITCH_STATUS_GENERR;
                }
 
 #ifdef DOTRACE 
                write(tech_pvt->fd, dtmf, (int) bread);
 #endif
-               result = sangoma_sendmsg_socket(tech_pvt->socket,
+               result = sangoma_sendmsg_socket(tech_pvt->wpsock->fd,
                                                                         &tech_pvt->hdrframe, sizeof(tech_pvt->hdrframe), dtmf, bread, 0);
                if (result < 0) {
                        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR,
@@ -557,7 +646,7 @@ static switch_status_t wanpipe_write_frame(switch_core_session_t *session, switc
                }
        }
 
-       if (switch_test_flag(tech_pvt, TFLAG_BYE) || tech_pvt->socket < 0) {
+       if (switch_test_flag(tech_pvt, TFLAG_BYE) || tech_pvt->wpsock->fd < 0) {
                return SWITCH_STATUS_GENERR;
        }
 
@@ -570,7 +659,7 @@ static switch_status_t wanpipe_write_frame(switch_core_session_t *session, switc
                unsigned int towrite;
 
 #if 1
-               if (sangoma_socket_waitfor(tech_pvt->socket, 1000, POLLOUT | POLLERR | POLLHUP) <= 0) {
+               if (sangoma_socket_waitfor(tech_pvt->wpsock->fd, 1000, POLLOUT | POLLERR | POLLHUP) <= 0) {
                        return SWITCH_STATUS_GENERR;
                }
 #endif
@@ -586,7 +675,7 @@ static switch_status_t wanpipe_write_frame(switch_core_session_t *session, switc
                        towrite = globals.mtu;
                }
 
-               result = sangoma_sendmsg_socket(tech_pvt->socket,
+               result = sangoma_sendmsg_socket(tech_pvt->wpsock->fd,
                                                                         &tech_pvt->hdrframe, sizeof(tech_pvt->hdrframe), bp, towrite, 0);
                if (result < 0) {
                        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR,
@@ -664,7 +753,8 @@ static switch_status_t wanpipe_kill_channel(switch_core_session_t *session, int
        switch_clear_flag(tech_pvt, TFLAG_MEDIA);
        switch_mutex_unlock(tech_pvt->flag_mutex);
 
-       sangoma_socket_close(&tech_pvt->socket);
+       //sangoma_socket_close(&tech_pvt->wpsock->fd);
+       //wp_close(tech_pvt);
 
        return SWITCH_STATUS_SUCCESS;
 
@@ -805,9 +895,9 @@ static switch_status_t wanpipe_outgoing_channel(switch_core_session_t *session,
 
                        if (bchan) {
                                int chan, span;
-                               
+
                                if (sangoma_span_chan_fromif(bchan, &span, &chan)) {
-                                       if ((tech_pvt->socket = sangoma_open_tdmapi_span_chan(span, chan)) < 0) {
+                                       if (!wp_open(tech_pvt, span, chan)) {
                                                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't open fd for s%dc%d! [%s]\n", span, chan, strerror(errno));
                                                switch_core_session_destroy(new_session);
                                                return SWITCH_STATUS_GENERR;
@@ -889,7 +979,7 @@ static switch_status_t wanpipe_outgoing_channel(switch_core_session_t *session,
                                                return SWITCH_STATUS_GENERR;
                                        }
 
-                                       if ((tech_pvt->socket = sangoma_open_tdmapi_span_chan(spri->span, channo)) < 0) {
+                                       if (!wp_open(tech_pvt, spri->span, channo)) {
                                                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't open fd!\n");
                                                switch_core_session_destroy(new_session);
                                                pri_sr_free(sr);
@@ -943,6 +1033,10 @@ SWITCH_MOD_DECLARE(switch_status_t) switch_module_load(const switch_loadable_mod
                return SWITCH_STATUS_TERM;
        }
 
+       memset(&globals, 0, sizeof(globals));
+       switch_core_hash_init(&globals.call_hash, module_pool);
+       switch_mutex_init(&globals.hash_mutex, SWITCH_MUTEX_NESTED, module_pool);
+
        /* start the pri's */
        if ((status = config_wanpipe(0)) != SWITCH_STATUS_SUCCESS) {
                return status;
@@ -1117,7 +1211,6 @@ static int on_ring(struct sangoma_pri *spri, sangoma_pri_event_t event_type, pri
 
        if ((session = switch_core_session_request(&wanpipe_endpoint_interface, NULL))) {
                struct private_object *tech_pvt;
-               int fd;
                char ani2str[4] = "";
                //wanpipe_tdm_api_t tdm_api;
 
@@ -1166,12 +1259,11 @@ static int on_ring(struct sangoma_pri *spri, sangoma_pri_event_t event_type, pri
                tech_pvt->callno = event->ring.channel;
                tech_pvt->span = spri->span;
 
-               if ((fd = sangoma_open_tdmapi_span_chan(spri->span, event->ring.channel)) < 0) {
+               if (!wp_open(tech_pvt, spri->span, event->ring.channel)) {
                        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't open fd!\n");
                }
                //sangoma_tdm_set_hw_period(fd, &tdm_api, 480);
 
-               tech_pvt->socket = fd;
                chanmap->map[event->ring.channel] = session;
 
                switch_channel_set_state(channel, CS_INIT);
@@ -1192,7 +1284,6 @@ static int check_flags(struct sangoma_pri *spri)
 
 static int on_restart(struct sangoma_pri *spri, sangoma_pri_event_t event_type, pri_event *event)
 {
-       int fd;
        switch_core_session_t *session;
        struct channel_map *chanmap;
 
@@ -1213,11 +1304,8 @@ static int on_restart(struct sangoma_pri *spri, sangoma_pri_event_t event_type,
                switch_channel_hangup(channel, SWITCH_CAUSE_NORMAL_CLEARING);
        }
        
-       if ((fd = sangoma_open_tdmapi_span_chan(spri->span, event->restart.channel)) < 0) {
-               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't open fd [%s]!\n", strerror(errno));
-       } else {
-               close(fd);
-       }
+       wp_restart(spri->span, event->restart.channel);
+
        return 0;
 }
 
@@ -1308,6 +1396,7 @@ static switch_status_t config_wanpipe(int reload)
        globals.dtmf_off = 50;
 
 
+
        if (!(xml = switch_xml_open_cfg(cf, &cfg, NULL))) {
                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "open of %s failed\n", cf);
                return SWITCH_STATUS_TERM;