]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
fix core
authorAnthony Minessale <anthony.minessale@gmail.com>
Fri, 17 Mar 2006 14:47:41 +0000 (14:47 +0000)
committerAnthony Minessale <anthony.minessale@gmail.com>
Fri, 17 Mar 2006 14:47:41 +0000 (14:47 +0000)
git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@863 d0543943-73ff-0310-b7d9-9358b9ac24b2

src/mod/codecs/mod_g729/mod_g729.c
src/mod/endpoints/mod_wanpipe/mod_wanpipe.c
src/switch_ivr.c

index bb851daf46f8cf214cefc5281bbbd06ed246443c..1ef51ed8e0f4fb1400d1cf2a75ca5cda44c1d15e 100644 (file)
@@ -189,7 +189,7 @@ static switch_status switch_g729_decode(switch_codec *codec,
        } else {
 
                switch_console_printf(SWITCH_CHANNEL_CONSOLE, "yo this frame is an odd size [%d]\n", encoded_data_len);
-
+               return SWITCH_STATUS_FALSE;
        }
 
 
@@ -202,6 +202,22 @@ static switch_status switch_g729_decode(switch_codec *codec,
 
 /* Registration */ 
 
+static const switch_codec_implementation g729_10ms_8k_implementation = { 
+       /*.samples_per_second */ 8000, 
+       /*.bits_per_second */ 32000, 
+       /*.microseconds_per_frame */ 10000, 
+       /*.samples_per_frame */ 80, 
+       /*.bytes_per_frame */ 160, 
+       /*.encoded_bytes_per_frame */ 10, 
+       /*.number_of_channels */ 1, 
+       /*.pref_frames_per_packet */ 1, 
+       /*.max_frames_per_packet */ 1, 
+       /*.init */ switch_g729_init, 
+       /*.encode */ switch_g729_encode, 
+       /*.decode */ switch_g729_decode, 
+       /*.destroy */ switch_g729_destroy, 
+};
+
 static const switch_codec_implementation g729_8k_implementation = { 
        /*.samples_per_second */ 8000, 
        /*.bits_per_second */ 64000, 
@@ -216,6 +232,7 @@ static const switch_codec_implementation g729_8k_implementation = {
        /*.encode */ switch_g729_encode, 
        /*.decode */ switch_g729_decode, 
        /*.destroy */ switch_g729_destroy, 
+       &g729_10ms_8k_implementation
 };
 
 
index 906244023254f17f1dca05c664c13d7a5e1c67b6..4fe709018e800bce468a2686a1f5b21d09166249 100644 (file)
@@ -34,7 +34,7 @@
 #include <libsangoma.h>
 #include <sangoma_pri.h>
 #include <libteletone.h>
-
+//#define DOTRACE
 static const char modname[] = "mod_wanpipe";
 #define STRLEN 15
 
@@ -61,6 +61,7 @@ typedef enum {
        TFLAG_DESTROY = (1 << 7),
        TFLAG_ABORT = (1 << 8),
        TFLAG_SWITCH = (1 << 9),
+       TFLAG_NOSIG = (1 << 10)
 } TFLAGS;
 
 
@@ -112,6 +113,12 @@ struct private_object {
        teletone_dtmf_detect_state_t dtmf_detect;
        teletone_generation_session_t tone_session;
        switch_buffer *dtmf_buffer;
+       unsigned int skip_read_frames;
+       unsigned int skip_write_frames;
+#ifdef DOTRACE
+       int fd;
+       int fd2;
+#endif
 };
 
 struct channel_map {
@@ -260,6 +267,10 @@ static switch_status wanpipe_on_init(switch_core_session *session)
        switch_core_session_set_read_codec(session, &tech_pvt->read_codec);
        switch_core_session_set_write_codec(session, &tech_pvt->write_codec);
 
+#ifdef DOTRACE 
+                                               tech_pvt->fd = open("/tmp/wp-in.raw", O_WRONLY | O_TRUNC | O_CREAT);
+                                               tech_pvt->fd2 = open("/tmp/wp-out.raw", O_WRONLY | O_TRUNC | O_CREAT);
+#endif
 
        /* Setup artificial DTMF stuff */
        memset(&tech_pvt->tone_session, 0, sizeof(tech_pvt->tone_session));
@@ -304,7 +315,7 @@ static switch_status wanpipe_on_hangup(switch_core_session *session)
 {
        struct private_object *tech_pvt;
        switch_channel *channel = NULL;
-       struct channel_map *chanmap;
+       struct channel_map *chanmap = NULL;
 
        
        channel = switch_core_session_get_channel(session);
@@ -313,7 +324,10 @@ static switch_status wanpipe_on_hangup(switch_core_session *session)
        tech_pvt = switch_core_session_get_private(session);
        assert(tech_pvt != NULL);
 
-       chanmap = tech_pvt->spri->private_info;
+
+       if (!switch_test_flag(tech_pvt, TFLAG_NOSIG)) {
+               chanmap = tech_pvt->spri->private_info;
+       }
 
        sangoma_socket_close(&tech_pvt->socket);
 
@@ -323,21 +337,22 @@ static switch_status wanpipe_on_hangup(switch_core_session *session)
 
        switch_console_printf(SWITCH_CHANNEL_CONSOLE, "WANPIPE HANGUP\n");
 
-       pri_hangup(tech_pvt->spri->pri, tech_pvt->call, tech_pvt->cause);
-       pri_destroycall(tech_pvt->spri->pri, tech_pvt->call);
+       if (!switch_test_flag(tech_pvt, TFLAG_NOSIG)) {
+               pri_hangup(tech_pvt->spri->pri, tech_pvt->call, tech_pvt->cause);
+               pri_destroycall(tech_pvt->spri->pri, tech_pvt->call);
 
-       if (chanmap->map[tech_pvt->callno]) {
-               chanmap->map[tech_pvt->callno] = NULL;
+               if (chanmap->map[tech_pvt->callno]) {
+                       chanmap->map[tech_pvt->callno] = NULL;
+               }
+               /*
+                 pri_hangup(tech_pvt->spri->pri,
+                 tech_pvt->hangup_event.hangup.call ? tech_pvt->hangup_event.hangup.call : tech_pvt->ring_event.ring.call,
+                 tech_pvt->cause);
+                 pri_destroycall(tech_pvt->spri->pri,
+                 tech_pvt->hangup_event.hangup.call ? tech_pvt->hangup_event.hangup.call : tech_pvt->ring_event.ring.call);
+               */
        }
 
-       /*
-       pri_hangup(tech_pvt->spri->pri,
-                          tech_pvt->hangup_event.hangup.call ? tech_pvt->hangup_event.hangup.call : tech_pvt->ring_event.ring.call,
-                          tech_pvt->cause);
-       pri_destroycall(tech_pvt->spri->pri,
-                                       tech_pvt->hangup_event.hangup.call ? tech_pvt->hangup_event.hangup.call : tech_pvt->ring_event.ring.call);
-       */
-
        teletone_destroy_session(&tech_pvt->tone_session);
 
        return SWITCH_STATUS_SUCCESS;
@@ -358,7 +373,21 @@ static switch_status wanpipe_on_transmit(switch_core_session *session)
 static switch_status wanpipe_outgoing_channel(switch_core_session *session, switch_caller_profile *outbound_profile,
                                                                                          switch_core_session **new_session, switch_memory_pool *pool)
 {
-       if (!globals.configured_spans) {
+       char *bchan = NULL;
+
+       if (outbound_profile && outbound_profile->destination_number) {
+               bchan = strchr(outbound_profile->destination_number, '%');
+       } else {
+               return SWITCH_STATUS_FALSE;
+       }
+
+       if (bchan) {
+               bchan++;
+               if (!bchan) {
+                       return SWITCH_STATUS_FALSE;
+               }
+               outbound_profile->destination_number++;
+       } else if (!globals.configured_spans) {
                switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Error No Spans Configured.\n");
                return SWITCH_STATUS_FALSE;
        }
@@ -381,6 +410,7 @@ static switch_status wanpipe_outgoing_channel(switch_core_session *session, swit
                        return SWITCH_STATUS_GENERR;
                }
 
+               
                if (outbound_profile) {
                        char name[128];
                        switch_caller_profile *caller_profile;
@@ -391,28 +421,29 @@ static switch_status wanpipe_outgoing_channel(switch_core_session *session, swit
                        struct channel_map *chanmap = NULL;
 
                        caller_profile = switch_caller_profile_clone(*new_session, outbound_profile);
-                       num = caller_profile->destination_number;
-                       if ((p = strchr(num, '/'))) {
-                               *p++ = '\0';
-                               if (*num != 'a') {
-                                       span = atoi(num);
-                               } else {
-                                       span = 1;
-                                       autospan = 1;
-                               }
-                               num = p;
+                       if (!bchan) {
+                               num = caller_profile->destination_number;
                                if ((p = strchr(num, '/'))) {
                                        *p++ = '\0';
-                                       if (*num == 'a') {
-                                               autochan = 1;
-                                       } else if (*num == 'A') {
-                                               autochan = -1;
+                                       if (*num != 'a') {
+                                               span = atoi(num);
                                        } else {
-                                               channo = atoi(num);
+                                               span = 1;
+                                               autospan = 1;
+                                       }
+                                       num = p;
+                                       if ((p = strchr(num, '/'))) {
+                                               *p++ = '\0';
+                                               if (*num == 'a') {
+                                                       autochan = 1;
+                                               } else if (*num == 'A') {
+                                                       autochan = -1;
+                                               } else {
+                                                       channo = atoi(num);
+                                               }
+                                               caller_profile->destination_number = p;
                                        }
-                                       caller_profile->destination_number = p;
                                }
-                               
                        }
 
                        snprintf(name, sizeof(name), "WanPipe/%s-%04x", caller_profile->destination_number, rand() & 0xffff);
@@ -420,79 +451,95 @@ static switch_status wanpipe_outgoing_channel(switch_core_session *session, swit
                        switch_channel_set_caller_profile(channel, caller_profile);
                        tech_pvt->caller_profile = caller_profile;
 
-
-                       do {
-                               if ((spri = &SPANS[span]->spri)) {
-                                       chanmap = spri->private_info;
-                                       if (channo == 0) {
-                                               if (autochan > 0) {
-                                                       for(channo = 1; channo < SANGOMA_MAX_CHAN_PER_SPAN; channo++) {
-                                                               if ((SPANS[span]->bchans & (1 << channo)) && !chanmap->map[channo]) {
-                                                                       switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Choosing channel %d\n", channo);
-                                                                       break;
+                       if (bchan) {
+                               int chan, span;
+                               sangoma_span_chan_fromif(bchan, &span, &chan);
+                               if (sangoma_span_chan_fromif(bchan, &span, &chan)) {
+                                       if ((tech_pvt->socket = sangoma_open_tdmapi_span_chan(span, chan)) < 0) {
+                                               switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Can't open fd!\n");
+                                               switch_core_session_destroy(new_session);
+                                               return SWITCH_STATUS_GENERR;
+                                       }
+                                       switch_set_flag(tech_pvt, TFLAG_NOSIG);
+                                       switch_channel_answer(channel);
+                               } else {
+                                       switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Invalid address\n");
+                                       switch_core_session_destroy(new_session);
+                                       return SWITCH_STATUS_GENERR;
+                               }
+                       } else {
+                               do {
+                                       if ((spri = &SPANS[span]->spri)) {
+                                               chanmap = spri->private_info;
+                                               if (channo == 0) {
+                                                       if (autochan > 0) {
+                                                               for(channo = 1; channo < SANGOMA_MAX_CHAN_PER_SPAN; channo++) {
+                                                                       if ((SPANS[span]->bchans & (1 << channo)) && !chanmap->map[channo]) {
+                                                                               switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Choosing channel %d\n", channo);
+                                                                               break;
+                                                                       }
                                                                }
-                                                       }
-                                               } else if (autochan < 0) {
-                                                       for(channo = SANGOMA_MAX_CHAN_PER_SPAN; channo > 0; channo--) {
-                                                               if ((SPANS[span]->bchans & (1 << channo)) && !chanmap->map[channo]) {
-                                                                       switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Choosing channel %d\n", channo);
-                                                                       break;
+                                                       } else if (autochan < 0) {
+                                                               for(channo = SANGOMA_MAX_CHAN_PER_SPAN; channo > 0; channo--) {
+                                                                       if ((SPANS[span]->bchans & (1 << channo)) && !chanmap->map[channo]) {
+                                                                               switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Choosing channel %d\n", channo);
+                                                                               break;
+                                                                       }
                                                                }
                                                        }
-                                               }
 
-                                               if (channo <= 0 || channo == (SANGOMA_MAX_CHAN_PER_SPAN)) {
-                                                       switch_console_printf(SWITCH_CHANNEL_CONSOLE, "No Free Channels!\n");
-                                                       channo = 0;
+                                                       if (channo <= 0 || channo == (SANGOMA_MAX_CHAN_PER_SPAN)) {
+                                                               switch_console_printf(SWITCH_CHANNEL_CONSOLE, "No Free Channels!\n");
+                                                               channo = 0;
+                                                       }
+                                               }
+                                               if (channo) {
+                                                       break;
                                                }
                                        }
-                                       if (channo) {
-                                               break;
-                                       }
-                               }
-                       } while(autospan && span < MAX_SPANS && !spri && !channo);
+                               } while(autospan && span < MAX_SPANS && !spri && !channo);
 
 
-                       if (!spri || channo == 0 || channo == (SANGOMA_MAX_CHAN_PER_SPAN)) {
-                               switch_console_printf(SWITCH_CHANNEL_CONSOLE, "No Free Channels!\n");
-                               switch_core_session_destroy(new_session);
-                               return SWITCH_STATUS_GENERR;
-                       }
-                       
-                       if (spri && (tech_pvt->call = pri_new_call(spri->pri))) {
-                               struct pri_sr *sr;
-
-                               sr = pri_sr_new();
-                               pri_sr_set_channel(sr, channo, 0, 0);
-                               pri_sr_set_bearer(sr, 0, SPANS[span]->l1);
-                               pri_sr_set_called(sr, caller_profile->destination_number, SPANS[span]->dp, 1);
-                               pri_sr_set_caller(sr,
-                                                                 caller_profile->caller_id_number,
-                                                                 caller_profile->caller_id_name,
-                                                                 SPANS[span]->dp,
-                                                                 PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN);
-                               pri_sr_set_redirecting(sr,
-                                                                          caller_profile->caller_id_number,
-                                                                          SPANS[span]->dp,
-                                                                          PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN,
-                                                                          PRI_REDIR_UNCONDITIONAL);
-                               
-                               if (pri_setup(spri->pri, tech_pvt->call , sr)) {
+                               if (!spri || channo == 0 || channo == (SANGOMA_MAX_CHAN_PER_SPAN)) {
+                                       switch_console_printf(SWITCH_CHANNEL_CONSOLE, "No Free Channels!\n");
                                        switch_core_session_destroy(new_session);
-                                       pri_sr_free(sr);
                                        return SWITCH_STATUS_GENERR;
                                }
-                               if ((tech_pvt->socket = sangoma_create_socket_intr(spri->span, channo)) < 0) {
-                                       switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Can't open fd!\n");
-                                       switch_core_session_destroy(new_session);
+                       
+                               if (spri && (tech_pvt->call = pri_new_call(spri->pri))) {
+                                       struct pri_sr *sr;
+
+                                       sr = pri_sr_new();
+                                       pri_sr_set_channel(sr, channo, 0, 0);
+                                       pri_sr_set_bearer(sr, 0, SPANS[span]->l1);
+                                       pri_sr_set_called(sr, caller_profile->destination_number, SPANS[span]->dp, 1);
+                                       pri_sr_set_caller(sr,
+                                                                         caller_profile->caller_id_number,
+                                                                         caller_profile->caller_id_name,
+                                                                         SPANS[span]->dp,
+                                                                         PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN);
+                                       pri_sr_set_redirecting(sr,
+                                                                                  caller_profile->caller_id_number,
+                                                                                  SPANS[span]->dp,
+                                                                                  PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN,
+                                                                                  PRI_REDIR_UNCONDITIONAL);
+                               
+                                       if (pri_setup(spri->pri, tech_pvt->call , sr)) {
+                                               switch_core_session_destroy(new_session);
+                                               pri_sr_free(sr);
+                                               return SWITCH_STATUS_GENERR;
+                                       }
+                                       if ((tech_pvt->socket = sangoma_create_socket_intr(spri->span, channo)) < 0) {
+                                               switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Can't open fd!\n");
+                                               switch_core_session_destroy(new_session);
+                                               pri_sr_free(sr);
+                                               return SWITCH_STATUS_GENERR;
+                                       }
                                        pri_sr_free(sr);
-                    return SWITCH_STATUS_GENERR;
+                                       chanmap->map[channo] = *new_session;
+                                       tech_pvt->spri = spri;
                                }
-                               pri_sr_free(sr);
-                               chanmap->map[channo] = *new_session;
-                               tech_pvt->spri = spri;
                        }
-                       
                } else {
                        switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Doh! no caller profile\n");
                        switch_core_session_destroy(new_session);
@@ -519,7 +566,7 @@ static switch_status wanpipe_answer_channel(switch_core_session *session)
        tech_pvt = switch_core_session_get_private(session);
        assert(tech_pvt != NULL);
 
-       if (switch_test_flag(tech_pvt, TFLAG_INBOUND)) {
+       if (switch_test_flag(tech_pvt, TFLAG_INBOUND) && !switch_test_flag(tech_pvt, TFLAG_NOSIG)) {
                pri_answer(tech_pvt->spri->pri, tech_pvt->call, 0, 1);
        }
        return SWITCH_STATUS_SUCCESS;
@@ -566,6 +613,7 @@ static switch_status wanpipe_read_frame(switch_core_session *session, switch_fra
                        } else {
                                return SWITCH_STATUS_GENERR;
                        }
+
                }
                bytes += res;
                bp += bytes;
@@ -586,6 +634,15 @@ static switch_status wanpipe_read_frame(switch_core_session *session, switch_fra
                }
        }
 
+       if (tech_pvt->skip_read_frames) {
+               memset(tech_pvt->read_frame.data, 255, tech_pvt->read_frame.datalen);
+               tech_pvt->skip_read_frames--;
+       }
+
+#ifdef DOTRACE 
+       write(tech_pvt->fd2, tech_pvt->read_frame.data, (int) tech_pvt->read_frame.datalen);
+#endif
+       //printf("read %d\n", tech_pvt->read_frame.datalen);
        *frame = &tech_pvt->read_frame;
        return SWITCH_STATUS_SUCCESS;
 }
@@ -608,6 +665,9 @@ static switch_status wanpipe_write_frame(switch_core_session *session, switch_fr
        tech_pvt = switch_core_session_get_private(session);
        assert(tech_pvt != NULL);
 
+
+       //printf("write %d\n", frame->datalen);
+
        while (tech_pvt->dtmf_buffer && bwrote < frame->datalen && bytes > 0 && (inuse = switch_buffer_inuse(tech_pvt->dtmf_buffer)) > 0) {
                if ((bread = switch_buffer_read(tech_pvt->dtmf_buffer, dtmf, globals.mtu)) < globals.mtu) {
                        while (bread < globals.mtu) {
@@ -615,6 +675,11 @@ static switch_status wanpipe_write_frame(switch_core_session *session, switch_fr
                        }
                }
                sangoma_socket_waitfor(tech_pvt->socket, -1, POLLOUT | POLLERR | POLLHUP);
+
+
+#ifdef DOTRACE 
+               write(tech_pvt->fd, dtmf, (int) bread);
+#endif
                res = sangoma_sendmsg_socket(tech_pvt->socket,
                                                                         &tech_pvt->hdrframe, sizeof(tech_pvt->hdrframe), dtmf, bread, 0);
                if (res < 0) {
@@ -635,10 +700,21 @@ static switch_status wanpipe_write_frame(switch_core_session *session, switch_fr
                }
        }
 
+       if (tech_pvt->skip_write_frames) {
+               tech_pvt->skip_write_frames--;
+               return SWITCH_STATUS_SUCCESS;
+       }
+
        while (bytes > 0) {
+               unsigned int towrite;
                sangoma_socket_waitfor(tech_pvt->socket, -1, POLLOUT | POLLERR | POLLHUP);
+#ifdef DOTRACE 
+               write(tech_pvt->fd, bp, (int) globals.mtu);
+#endif
+               towrite = bytes >= globals.mtu ? globals.mtu : bytes;
+       
                res = sangoma_sendmsg_socket(tech_pvt->socket,
-                                                                        &tech_pvt->hdrframe, sizeof(tech_pvt->hdrframe), bp, globals.mtu, 0);
+                                                                        &tech_pvt->hdrframe, sizeof(tech_pvt->hdrframe), bp, towrite, 0);
                if (res < 0) {
                        switch_console_printf(SWITCH_CHANNEL_CONSOLE,
                                                                  "Bad Write frame len %d write %d bytes returned %d (%s)!\n", frame->datalen,
@@ -688,6 +764,8 @@ static switch_status wanpipe_send_dtmf(switch_core_session *session, char *digit
                }
        }
 
+       tech_pvt->skip_read_frames = 200;
+       
        return status;
 }
 
@@ -843,6 +921,7 @@ static int on_answer(struct sangoma_pri *spri, sangoma_pri_event_t event_type, p
        switch_channel *channel;
        struct channel_map *chanmap;
 
+
        chanmap = spri->private_info;
 
        if ((session = chanmap->map[event->answer.channel])) {
@@ -853,7 +932,7 @@ static int on_answer(struct sangoma_pri *spri, sangoma_pri_event_t event_type, p
        } else {
                switch_console_printf(SWITCH_CHANNEL_CONSOLE, "-- Answer on channel %d but it's not in use?\n", event->answer.channel);
        }
-
+       
        return 0;
 }
 
index a6cab30b77924e4cbd47bd893d3db7795b63cf27..7cc4fac1dca97d503e333ba804394eb2b0dc2646 100644 (file)
@@ -691,6 +691,7 @@ static void *audio_bridge_thread(switch_thread *thread, void *obj)
        int stream_id = 0, ans_a = 0, ans_b = 0;
        switch_dtmf_callback_function dtmf_callback;
        void *user_data;
+       int *his_status;
 
        switch_channel *chan_a, *chan_b;
        switch_frame *read_frame;
@@ -702,6 +703,7 @@ static void *audio_bridge_thread(switch_thread *thread, void *obj)
        stream_id_p = data->objs[2];
        dtmf_callback = data->objs[3];
        user_data = data->objs[4];
+       his_status = data->objs[5];
 
        if (stream_id_p) {
                stream_id = *stream_id_p;
@@ -715,7 +717,7 @@ static void *audio_bridge_thread(switch_thread *thread, void *obj)
        ans_b = switch_channel_test_flag(chan_b, CF_ANSWERED);
 
 
-       while (data->running > 0) {
+       while (data->running > 0 && *his_status > 0) {
                switch_channel_state b_state = switch_channel_get_state(chan_b);
 
                switch (b_state) {
@@ -877,7 +879,7 @@ SWITCH_DECLARE(switch_status) switch_ivr_multi_threaded_bridge(switch_core_sessi
        other_audio_thread.objs[2] = &stream_id;
        other_audio_thread.objs[3] = dtmf_callback;
        other_audio_thread.objs[4] = session_data;
-
+       other_audio_thread.objs[5] = &this_audio_thread.running;
        other_audio_thread.running = 5;
 
        this_audio_thread.objs[0] = peer_session;
@@ -885,6 +887,7 @@ SWITCH_DECLARE(switch_status) switch_ivr_multi_threaded_bridge(switch_core_sessi
        this_audio_thread.objs[2] = &stream_id;
        this_audio_thread.objs[3] = dtmf_callback;
        this_audio_thread.objs[4] = peer_session_data;
+       this_audio_thread.objs[5] = &other_audio_thread.running;
        this_audio_thread.running = 2;