]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
let unicast mode operate on the native codec if desired
authorAnthony Minessale <anthony.minessale@gmail.com>
Fri, 13 Apr 2007 16:24:02 +0000 (16:24 +0000)
committerAnthony Minessale <anthony.minessale@gmail.com>
Fri, 13 Apr 2007 16:24:02 +0000 (16:24 +0000)
git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@4925 d0543943-73ff-0310-b7d9-9358b9ac24b2

scripts/socket/socket2me/socket2me.c
src/include/switch_ivr.h
src/include/switch_types.h
src/switch_ivr.c

index 013c982ee9f831504d272c4055e76c99218146e0..128030c0a3ad3e9536d4cd1a4e821bbc115e7ad5 100644 (file)
@@ -42,6 +42,7 @@
 #include <unistd.h>
 #include <spandsp.h>
 
+
 #define SOCKET2ME_DEBUG 0
 #define MAXPENDING 10000
 #define RCVBUFSIZE 4198
@@ -178,7 +179,9 @@ void client_run(int client_socket, char *local_ip, int local_port, char *remote_
     fax_state_t fax;
        char tmp[512], fn[512], *file_name = "/tmp/test.tiff";
        int send_fax = FALSE;
-       
+       int g711 = 0;
+       int pcmu = 0;
+
        snprintf(sendbuf, sizeof(sendbuf), "connect\n\n");
        send(client_socket, sendbuf, strlen(sendbuf), 0);
 
@@ -189,17 +192,32 @@ void client_run(int client_socket, char *local_ip, int local_port, char *remote_
 #if SOCKET2ME_DEBUG
        printf("READ [%s]\n", infobuf);
 #endif
+
+       if (cheezy_get_var(infobuf, "Channel-Read-Codec-Name", tmp, sizeof(tmp))) {
+               if (!strcasecmp(tmp, "pcmu")) {
+                       g711 = 1;
+                       pcmu = 1;
+               } else if (!strcasecmp(tmp, "pcma")) {
+                       g711 = 1;
+               }
+       }
+
+
        snprintf(sendbuf, sizeof(sendbuf), "sendmsg\n"
                         "call-command: unicast\n"
                         "local_ip: %s\n"
                         "local_port: %d\n"
                         "remote_ip: %s\n"
                         "remote_port: %d\n"
-                        "transport: udp\n\n",
+                        "transport: udp\n"
+                        "%s"
+                        "\n",
                         local_ip, local_port,
-                        remote_ip, remote_port
+                        remote_ip, remote_port,
+                        g711 ? "flags: native\n" : ""
                         );
 
+       
        if (cheezy_get_var(infobuf, "variable_fax_file_name", fn, sizeof(fn))) {
                file_name = fn;
        }
@@ -267,8 +285,9 @@ void client_run(int client_socket, char *local_ip, int local_port, char *remote_
        for (;;) {
                struct sockaddr_in local_addr = {0};
         int cliAddrLen = sizeof(local_addr);
-               short audioBuffer[1024], outbuf[1024];
-               int tx, bigger;
+               unsigned char audiobuf[1024], rawbuf[1024], outbuf[1024];
+               short *usebuf = NULL;
+               int tx, tx_bytes, bigger, sample_count;
                fd_set ready;
 
                FD_ZERO(&ready);
@@ -297,23 +316,62 @@ void client_run(int client_socket, char *local_ip, int local_port, char *remote_
                        continue;
                }
 
-        if ((read_bytes = recvfrom(usock, audioBuffer, sizeof(audioBuffer), 0, (struct sockaddr *) &local_addr, &cliAddrLen)) < 0) {
+        if ((read_bytes = recvfrom(usock, audiobuf, sizeof(audiobuf), 0, (struct sockaddr *) &local_addr, &cliAddrLen)) < 0) {
                        die("recvfrom() failed");
                }
 
-               fax_rx(&fax, (int16_t *)audioBuffer, read_bytes / 2);
+               if (g711) {
+                       int i;
+                       short *rp = (short *) rawbuf;
+                       
+                       for (i = 0; i < read_bytes; i++) {
+                               if (pcmu) {
+                                       rp[i] = ulaw_to_linear(audiobuf[i]);
+                               } else {
+                                       rp[i] = alaw_to_linear(audiobuf[i]);
+                               }
+                       }
+                       usebuf = rp;
+                       sample_count = read_bytes;
+               } else {
+                       usebuf = (short *) audiobuf;
+                       sample_count = read_bytes / 2;
+               }
+               
+               fax_rx(&fax, usebuf, sample_count);
 #if SOCKET2ME_DEBUG
                printf("Handling client %s:%d %d bytes\n", inet_ntoa(local_addr.sin_addr), ntohs(local_addr.sin_port), read_bytes);
 #endif
-        if ((tx = fax_tx(&fax, (int16_t *) &outbuf, read_bytes / 2)) < 0) {
+
+               
+               if ((tx = fax_tx(&fax, (short *)outbuf, sample_count)) < 0) {
             printf("Fax Error\n");
                        break;
         } else if (!tx) {
                        continue;
                }
                
+
+               if (g711) {
+                       int i;
+                       short *bp = (short *) outbuf;
+                       for (i = 0; i < tx; i++) {
+                               if (pcmu) {
+                                       rawbuf[i] = linear_to_ulaw(bp[i]);
+                               } else {
+                                       rawbuf[i] = linear_to_alaw(bp[i]);
+                               }
+                       }
+                       usebuf = (short *) rawbuf;
+                       tx_bytes = tx;
+               } else {
+                       usebuf = (short *)outbuf;
+                       tx_bytes = tx * 2;
+               }       
+               
+
                cliAddrLen = sizeof(sendaddr);
-        if (sendto(usock, outbuf, tx * 2, 0, (struct sockaddr *) &sendaddr, sizeof(sendaddr)) != tx * 2) {
+        if (sendto(usock, usebuf, tx_bytes, 0, (struct sockaddr *) &sendaddr, sizeof(sendaddr)) != sample_count) {
                        die("sendto() sent a different number of bytes than expected");
                }
        }
index dde50511856d1224d27dc6687d22486c51d8a5b9..a66ce41562431ff45d9fcda282b312513328d67a 100644 (file)
@@ -78,7 +78,8 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_activate_unicast(switch_core_session_
                                                                                                                        switch_port_t local_port,
                                                                                                                        char *remote_ip,
                                                                                                                        switch_port_t remote_port,
-                                                                                                                       char *transport);
+                                                                                                                       char *transport,
+                                                                                                                       char *flags);
 
 /*!
   \brief Generate an XML CDR report.
index 5e0cf4a7cc5842a212d88e0ce2ee72566250f8ca..d3625db2857868bddcf9aac69d9134b9190ef106 100644 (file)
@@ -121,7 +121,8 @@ SWITCH_BEGIN_EXTERN_C
 typedef enum {
        SUF_NONE = 0,
        SUF_THREAD_RUNNING = (1 << 0),
-       SUF_READY = (1 << 1)
+       SUF_READY = (1 << 1),
+       SUF_NATIVE = (1 << 2)
 } switch_unicast_flag_t;
 
 typedef enum {
index f41a24b13495b0150ceba879aa69808e97ee8d2d..5566f55c9790a2fcda1afe52debb4731929d9e04 100644 (file)
@@ -140,7 +140,9 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_deactivate_unicast(switch_core_sessio
                                        break;
                                }
                        }
-                       switch_core_codec_destroy(&conninfo->read_codec);
+                       if (conninfo->read_codec.implementation) {
+                               switch_core_codec_destroy(&conninfo->read_codec);
+                       }
                        switch_socket_close(conninfo->socket);
                }
                switch_channel_clear_flag(channel, CF_UNICAST);
@@ -156,7 +158,8 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_activate_unicast(switch_core_session_
                                                                                                                        switch_port_t local_port,
                                                                                                                        char *remote_ip,
                                                                                                                        switch_port_t remote_port,
-                                                                                                                       char *transport)
+                                                                                                                       char *transport,
+                                                                                                                       char *flags)
 {
        switch_channel_t *channel;
        switch_unicast_conninfo_t *conninfo;
@@ -186,29 +189,37 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_activate_unicast(switch_core_session_
                goto fail;
        }
 
+       if (flags) {
+               if (strstr(flags, "native")) {
+                       switch_set_flag(conninfo, SUF_NATIVE);
+               }
+       }
+
        switch_mutex_init(&conninfo->flag_mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(session));
        
        read_codec = switch_core_session_get_read_codec(session);
        
-       if (switch_core_codec_init(&conninfo->read_codec,
-                                                          "L16",
-                                                          NULL,
-                                                          read_codec->implementation->samples_per_second,
-                                                          read_codec->implementation->microseconds_per_frame / 1000,
-                                                          1, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE,
-                                                          NULL, switch_core_session_get_pool(session)) == SWITCH_STATUS_SUCCESS) {
-               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG,
-                                                 "Raw Codec Activation Success L16@%uhz 1 channel %dms\n",
-                                                 read_codec->implementation->samples_per_second, read_codec->implementation->microseconds_per_frame / 1000);
-       } else {
-               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Raw Codec Activation Failed L16@%uhz 1 channel %dms\n",
-                                                 read_codec->implementation->samples_per_second, read_codec->implementation->microseconds_per_frame / 1000);
-               goto fail;
+       if (!switch_test_flag(conninfo, SUF_NATIVE)) {
+               if (switch_core_codec_init(&conninfo->read_codec,
+                                                                  "L16",
+                                                                  NULL,
+                                                                  read_codec->implementation->samples_per_second,
+                                                                  read_codec->implementation->microseconds_per_frame / 1000,
+                                                                  1, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE,
+                                                                  NULL, switch_core_session_get_pool(session)) == SWITCH_STATUS_SUCCESS) {
+                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG,
+                                                         "Raw Codec Activation Success L16@%uhz 1 channel %dms\n",
+                                                         read_codec->implementation->samples_per_second, read_codec->implementation->microseconds_per_frame / 1000);
+               } else {
+                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Raw Codec Activation Failed L16@%uhz 1 channel %dms\n",
+                                                         read_codec->implementation->samples_per_second, read_codec->implementation->microseconds_per_frame / 1000);
+                       goto fail;
+               }
        }
 
        conninfo->write_frame.data = conninfo->write_frame_data;
        conninfo->write_frame.buflen = sizeof(conninfo->write_frame_data);
-       conninfo->write_frame.codec = &conninfo->read_codec;
+       conninfo->write_frame.codec = switch_test_flag(conninfo, SUF_NATIVE) ? read_codec : &conninfo->read_codec;
        
 
        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "connect %s:%d->%s:%d\n",
@@ -307,6 +318,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_parse_event(switch_core_session_t *se
                char *remote_ip = switch_event_get_header(event, "remote_ip");
                char *remote_port = switch_event_get_header(event, "remote_port");
                char *transport = switch_event_get_header(event, "transport");
+               char *flags = switch_event_get_header(event, "flags");
 
                if (switch_strlen_zero(local_ip)) {
                        local_ip = "127.0.0.1";
@@ -324,7 +336,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_parse_event(switch_core_session_t *se
                        transport = "udp";
                }
 
-               switch_ivr_activate_unicast(session, local_ip, (switch_port_t)atoi(local_port), remote_ip, (switch_port_t)atoi(remote_port), transport);
+               switch_ivr_activate_unicast(session, local_ip, (switch_port_t)atoi(local_port), remote_ip, (switch_port_t)atoi(remote_port), transport, flags);
 
        } else if (cmd_hash == CMD_HANGUP) {
                char *cause_name = switch_event_get_header(event, "hangup-cause");
@@ -383,9 +395,9 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_park(switch_core_session_t *session,
                                                unicast_thread_launch(conninfo);
                                        }
                                }
-
+                               
                                if (conninfo) {
-                                       switch_size_t len;
+                                       switch_size_t len = 0;
                                        uint32_t flags = 0;
                                        switch_byte_t decoded[SWITCH_RECOMMENDED_BUFFER_SIZE];
                                        uint32_t rate = read_codec->implementation->samples_per_second;
@@ -400,14 +412,17 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_park(switch_core_session_t *session,
                                                sendbuf = decoded;
                                                status = SWITCH_STATUS_SUCCESS;
                                        } else {
-                                       
-                                               status = switch_core_codec_decode(
-                                                                                                                 read_codec,
-                                                                                                                 &conninfo->read_codec,
-                                                                                                                 read_frame->data,
-                                                                                                                 read_frame->datalen,
-                                                                                                                 read_codec->implementation->samples_per_second,
-                                                                                                                 decoded, &dlen, &rate, &flags);
+                                               if (switch_test_flag(conninfo, SUF_NATIVE)) {
+                                                       status = SWITCH_STATUS_NOOP;
+                                               } else {
+                                                       status = switch_core_codec_decode(
+                                                                                                                         read_codec,
+                                                                                                                         &conninfo->read_codec,
+                                                                                                                         read_frame->data,
+                                                                                                                         read_frame->datalen,
+                                                                                                                         read_codec->implementation->samples_per_second,
+                                                                                                                         decoded, &dlen, &rate, &flags);
+                                               }
                                                switch (status) {
                                                case SWITCH_STATUS_NOOP:
                                                case SWITCH_STATUS_BREAK:
@@ -435,7 +450,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_park(switch_core_session_t *session,
                                        }
                                }
                        }
-
+                       
                        if (switch_core_session_dequeue_private_event(session, &event) == SWITCH_STATUS_SUCCESS) {
                                switch_ivr_parse_event(session, event);
                                switch_channel_event_set_data(switch_core_session_get_channel(session), event);