Add mbtk_loopbuff and rtp support.

Change-Id: Idc80af4efb8ff76c4afc59fdf1d3896b453e6ff4
diff --git a/mbtk/test/libmbtk_audio/Makefile b/mbtk/test/libmbtk_audio/Makefile
index 99172c3..d6e275c 100755
--- a/mbtk/test/libmbtk_audio/Makefile
+++ b/mbtk/test/libmbtk_audio/Makefile
@@ -7,7 +7,7 @@
 
 LIBS += -lmbtk_lib
 
-CFLAGS += 
+CFLAGS = $(CFLAGS_TEST)
 
 DEFINE +=
 
diff --git a/mbtk/test/libmbtk_audio/mbtk_pcm_voip_test.c b/mbtk/test/libmbtk_audio/mbtk_pcm_voip_test.c
new file mode 100755
index 0000000..20938ff
--- /dev/null
+++ b/mbtk/test/libmbtk_audio/mbtk_pcm_voip_test.c
@@ -0,0 +1,222 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <pthread.h>
+#include <errno.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <signal.h>
+
+#include "audio_if_api.h"
+#include "mbtk_audio2.h"
+#include "mbtk_log.h"
+#include "mbtk_utils.h"
+
+#define BUFF_SIZE 4096
+
+#define ID_RIFF 0x46464952
+#define ID_WAVE 0x45564157
+#define ID_FMT  0x20746d66
+#define ID_DATA 0x61746164
+#define FORMAT_PCM 1
+
+#define PCM_WB_BUF_SIZE     640
+#define PCM_NARROW_BUF_SIZE 320
+
+static int record_fd = -1;
+static bool running = FALSE;
+
+static void recorder_cb(void *data, uint32 data_len)
+{
+    if(record_fd > 0) {
+        if(data_len > 0) {
+            LOGD("Recorver data:%d", data_len);
+            mbtk_write(record_fd, data, data_len);
+        } else {
+            LOGD("Recorver data end.");
+        }
+    }
+}
+
+static void voip_playback_run(void *arg)
+{
+    int rc, len, fd, frames = 0;
+    int pack_size = 1024;
+    //char buf[MBTK_PCM_WB_BUF_SIZE];
+    char buf[BUFF_SIZE];
+    char *path = "/data/voip_playback.wav";
+    struct stat st;
+    struct riff_wave_header riff_wave_header;
+    struct chunk_header chunk_header;
+    struct chunk_fmt chunk_fmt = {0};
+    unsigned int more_chunks = 1;
+
+    /* Check and open source file */
+    if (access(path, F_OK) || stat(path, &st)) {
+        printf("%s: error reading from file %s\n", __FUNCTION__, path);
+        return;
+    }
+
+    if (!st.st_size) {
+        printf("%s: empty file %s\n", __FUNCTION__, path);
+        return;
+    }
+
+    fd = open(path, O_RDONLY);
+    if (fd < 0) {
+        printf("%s: error opening file %s\n", __FUNCTION__, path);
+        return;
+    }
+
+    lseek(fd, sizeof(struct wav_header), SEEK_SET);
+
+
+    if(mbtk_audio_voice_pcm_playback_start()) {
+        printf("mbtk_audio_voice_pcm_playback_start() fail.\n");
+        return;
+    }
+
+#if 1
+    if(mbtk_audio_voice_pcm_record_start(recorder_cb)) {
+        printf("mbtk_audio_voice_pcm_record_start() fail.\n");
+        //goto exit;
+    }
+#endif
+
+    while (running) {
+        /* Playback loop */
+        memset(buf, 0x00, sizeof(buf));
+        len = read(fd, buf, pack_size);
+        if (len == -1) {
+            printf("%s: error reading from file\n", __FUNCTION__);
+            break;
+        }
+
+        if (len == 0) {
+            /* reached EOF */
+            printf("%s: nothing to read\n", __FUNCTION__);
+            break;
+        }
+
+        if((rc = mbtk_audio_pcm_play_data_send(buf, len)) < len) {
+            printf("Send data %d/%d\n", rc, len);
+            break;
+        }
+
+        printf("%s: No.%d frame playback[len - %d]\n", __FUNCTION__, ++frames, len);
+    }
+
+#if 1
+    if(mbtk_audio_pcm_recorder_stop()) {
+        printf("mbtk_audio_pcm_recorder_stop() fail.\n");
+        //goto exit;
+    }
+#endif
+
+    LOGD("playback_thread exit.");
+}
+
+#if 0
+static void voip_record_run(void *arg)
+{
+
+}
+#endif
+
+static void sig_handler(int sig)
+{
+    running = FALSE;
+
+    printf("Success exit by signal...\n");
+
+    sleep(1);
+
+    exit(0);
+}
+
+
+int main(int argc, char *argv[])
+{
+    mbtk_log_init("radio", "RTP_TEST");
+
+    signal(SIGINT, sig_handler);
+    signal(SIGTERM, sig_handler);
+
+    if(mbtk_audio_pcm_init()) {
+        printf("mbtk_audio_pcm_init() fail.\n");
+        return -1;
+    }
+
+    struct wav_header header;
+    int rc = 0;
+    char *path = "/data/voip_record.wav";
+
+    header.riff_id = ID_RIFF;
+    header.riff_sz = 0;
+    header.riff_fmt = ID_WAVE;
+    header.fmt_id = ID_FMT;
+    header.fmt_sz = 16;
+    header.audio_format = 1;        //FORMAT_PCM;
+    header.num_channels = 1;        //Modem ONLY support mono recording
+    header.sample_rate = 8000;
+    header.bits_per_sample = 16;    //PCM_SAMPLEBITS_S16_LE;
+    header.byte_rate = (header.bits_per_sample / 8) * header.num_channels * header.sample_rate;
+    header.block_align = header.num_channels * (header.bits_per_sample / 8);
+    header.data_id = ID_DATA;
+
+    record_fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, 0644);
+    if (record_fd < 0) {
+        printf("%s: error opening file %s!\n", __FUNCTION__, path);
+        rc = -1;
+        goto exit;
+    }
+
+    //leave enough room for header
+    lseek(record_fd, sizeof(struct wav_header), SEEK_SET);
+
+    running = TRUE;
+
+    pthread_t playabck_thread/*, record_thread*/;
+    rc = pthread_create(&playabck_thread, NULL, (void *)&voip_playback_run, NULL);
+    if (rc < 0) {
+        LOGE("error creating thread_start!");
+        rc = -1;
+        goto exit;
+    }
+
+#if 0
+    rc = pthread_create(&record_thread, NULL, (void *)&voip_record_run, NULL);
+    if (rc < 0) {
+        LOGE("error creating thread_start!");
+        rc = -1;
+        goto exit;
+    }
+#endif
+
+    if (pthread_join(playabck_thread, NULL)){
+        printf("error join thread!\n");
+        abort();
+    }
+    LOGD("playabck_thread() join exit.");
+
+    lseek(record_fd, 0, SEEK_SET);
+    mbtk_write(record_fd, &header, sizeof(struct wav_header));
+    close(record_fd);
+
+#if 0
+    if (pthread_join(record_thread, NULL)){
+        printf("error join thread!\n");
+        abort();
+    }
+    LOGD("record_thread() join exit.");
+#endif
+
+exit:
+    if(mbtk_audio_pcm_deinit()) {
+        printf("mbtk_audio_pcm_deinit() fail.\n");
+        return -1;
+    }
+    return rc;
+}
+
diff --git a/mbtk/test/libmbtk_lib/mbtk_loopbuff_test.c b/mbtk/test/libmbtk_lib/mbtk_loopbuff_test.c
new file mode 100755
index 0000000..4ae6684
--- /dev/null
+++ b/mbtk/test/libmbtk_lib/mbtk_loopbuff_test.c
@@ -0,0 +1,107 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <errno.h>
+#include <unistd.h>
+#include <time.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <pthread.h>
+
+#include "mbtk_loop_buffer.h"
+#include "mbtk_log.h"
+#include "mbtk_utils.h"
+
+
+static void* read_run(void* arg)
+{
+    mbtk_loop_buff_handle *handle = (mbtk_loop_buff_handle*)arg;
+    int fd = open("/data/voip_playback.wav", O_RDONLY);
+    int read_count = 0;
+    int buff_count = 0;
+    if(fd > 0) {
+        char buff[1569];
+        int len;
+        int temp_len;
+        while((len = read(fd, buff, sizeof(buff))) > 0) {
+            read_count += len;
+
+            temp_len = mbtk_loopbuff_writen(handle, buff, len);
+            if(temp_len > 0) {
+                if(temp_len != len) {
+                    printf("mbtk_loopbuff_writen() fail : %d/%d\n", temp_len, len);
+                }
+                buff_count += temp_len;
+            } else {
+                printf("mbtk_loopbuff_writen() fail.\n");
+            }
+        }
+        close(fd);
+    }
+    printf("read complete : %d / %d\n", read_count, buff_count);
+
+    return NULL;
+}
+
+static void* write_run(void* arg)
+{
+    mbtk_loop_buff_handle *handle = (mbtk_loop_buff_handle*)arg;
+    int write_count = 0;
+    int buff_count = 0;
+    int fd = open("/data/voip_playback_copy.wav", O_WRONLY | O_CREAT | O_TRUNC, 0644);
+    if(fd > 0) {
+        char buff[999];
+        int len;
+        while((len = mbtk_loopbuff_readn(handle, buff, sizeof(buff))) > 0) {
+            buff_count += len;
+            len = write(fd, buff, len);
+            if(len > 0)
+                write_count += len;
+            else
+                printf("mbtk_write() fail.\n");
+        }
+        close(fd);
+    }
+
+    printf("write complete : %d / %d\n", write_count, buff_count);
+    return NULL;
+}
+
+int main(int argc, char *argv[])
+{
+    mbtk_log_init("radio", "LOOPBUFF");
+    mbtk_loop_buff_handle *handle = mbtk_loopbuff_get(7 * 1001);
+    if(handle) {
+        pthread_t read_pid, write_pid;
+        if(pthread_create(&read_pid, NULL, read_run, handle))
+        {
+            LOGE("pthread_create() fail.");
+            return -1;
+        }
+
+        if(pthread_create(&write_pid, NULL, write_run, handle))
+        {
+            LOGE("pthread_create() fail.");
+            return -1;
+        }
+
+        sleep(1);
+
+        if (pthread_join(read_pid, NULL)){
+            printf("error join thread!\n");
+            abort();
+        }
+
+        if (pthread_join(write_pid, NULL)){
+            printf("error join thread!\n");
+            abort();
+        }
+
+        mbtk_loopbuff_free(handle);
+    }
+    return 0;
+}
+
+
diff --git a/mbtk/test/libmbtk_lib/mbtk_rtp_test.c b/mbtk/test/libmbtk_lib/mbtk_rtp_test.c
new file mode 100755
index 0000000..2140e25
--- /dev/null
+++ b/mbtk/test/libmbtk_lib/mbtk_rtp_test.c
@@ -0,0 +1,155 @@
+#include <sys/stat.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "mbtk_rtp.h"
+#include "mbtk_log.h"
+
+
+static void help()
+{
+    printf("rtp_mode <0/1>: Disable/Enable RTP.\n");
+    printf("volume <0-7>: Set volume.\n");
+    printf("remote_ip <xxx:xxx:xxx:xxx>: Set remote ip.\n");
+    printf("client_port <port>: Set client(local) port.\n");
+    printf("server_port <port>: Set server(remote) port.\n");
+    printf("sample_rate <8000/16000>: Set sample rate.\n");
+    printf("channel <1>: Set channel.\n");
+}
+
+
+static void sig_handler(int sig)
+{
+    if(mbtk_rtp_deinit()) {
+        printf("mbtk_rtp_deinit() fail.\n");
+    }
+
+    printf("Success exit by signal...\n");
+    exit(0);
+}
+
+int main(int argc, char *argv[])
+{
+    mbtk_log_init("radio", "RTP_CLI");
+
+    if(mbtk_rtp_init()) {
+        printf("mbtk_rtp_init() fail.\n");
+        return -1;
+    }
+
+    signal(SIGINT, sig_handler);
+    signal(SIGTERM, sig_handler);
+
+    char cmd[100];
+    bool running = TRUE;
+    while(running)
+    {
+        memset(cmd, 0, 100);
+//        int err;
+        // printf("0 : Disable    1 : Enable    Other : Exit\n");
+        help();
+        if(fgets(cmd, 100, stdin))
+        {
+            if(cmd[0] == '\r' || cmd[0] == '\n')
+                continue;
+            char *ptr = cmd + strlen(cmd) - 1;
+            while(ptr >= cmd && (*ptr == '\r' || *ptr == '\n'))
+            {
+                *ptr-- = '\0';
+            }
+
+            if(!strncasecmp(cmd, "rtp_mode", 8))
+            {
+                int temp;
+                if(1 == sscanf(cmd, "rtp_mode %d", &temp)) {
+                    if(mbtk_rtp_enable((bool)temp)) {
+                        printf("Error\n");
+                    } else {
+                        printf("Success\n");
+                    }
+                }
+            }
+            else if(!strncasecmp(cmd, "volume", 6)){
+                int temp;
+                if(1 == sscanf(cmd, "volume %d", &temp)) {
+                    if(mbtk_rtp_volume_set(temp)) {
+                        printf("Error\n");
+                    } else {
+                        printf("Success\n");
+                    }
+                }
+            }
+            else if(!strncasecmp(cmd, "remote_ip", 9)){
+                char ipv4[20] = {0};
+                if(1 == sscanf(cmd, "remote_ip %s", ipv4)) {
+                    if(mbtk_rtp_remote_ip_set(ipv4)) {
+                        printf("Error\n");
+                    } else {
+                        printf("Success\n");
+                    }
+                }
+            }
+            else if(!strncasecmp(cmd, "client_port", 11)){
+                int temp;
+                if(1 == sscanf(cmd, "client_port %d", &temp)) {
+                    if(mbtk_rtp_client_port_set(temp)) {
+                        printf("Error\n");
+                    } else {
+                        printf("Success\n");
+                    }
+                }
+            }
+            else if(!strncasecmp(cmd, "server_port", 11)){
+                int temp;
+                if(1 == sscanf(cmd, "server_port %d", &temp)) {
+                    if(mbtk_rtp_server_port_set(temp)) {
+                        printf("Error\n");
+                    } else {
+                        printf("Success\n");
+                    }
+                }
+            }
+            else if(!strncasecmp(cmd, "sample_rate", 11)){
+                int temp;
+                if(1 == sscanf(cmd, "sample_rate %d", &temp)) {
+                    if(mbtk_rtp_sample_rate_set(temp)) {
+                        printf("Error\n");
+                    } else {
+                        printf("Success\n");
+                    }
+                }
+            }
+            else if(!strncasecmp(cmd, "channel", 7)){
+                int temp;
+                if(1 == sscanf(cmd, "channel %d", &temp)) {
+                    if(mbtk_rtp_channel_set(temp)) {
+                        printf("Error\n");
+                    } else {
+                        printf("Success\n");
+                    }
+                }
+            }
+
+            else if(!strcasecmp(cmd, "h") || !strcasecmp(cmd, "help")) {
+                help();
+            } else if(!strcasecmp(cmd, "q")) {
+                break;
+            } else {
+                printf("\n");
+            }
+        }
+    }
+
+//exit:
+    if(mbtk_rtp_deinit()) {
+        printf("mbtk_rtp_deinit() fail.\n");
+        return -1;
+    }
+
+    printf("Success exit.\n");
+    return 0;
+}
diff --git a/mbtk/test/others/mbtk_rtp_udp_cli.c b/mbtk/test/others/mbtk_rtp_udp_cli.c
new file mode 100755
index 0000000..92c19cf
--- /dev/null
+++ b/mbtk/test/others/mbtk_rtp_udp_cli.c
@@ -0,0 +1,373 @@
+#include <stdio.h>
+#include <errno.h>
+#include <pthread.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <netinet/in.h>
+#include <sys/epoll.h>
+#include <arpa/inet.h>
+#include <sys/ioctl.h>
+#include <signal.h>
+#include <stdbool.h>
+#include <sys/stat.h>
+
+//#include "mbtk_log.h"
+//#include "mbtk_utils.h"
+// #include "audio_if_api.h"
+//#include "mbtk_audio2.h"
+
+#define RTP_UDP_SER_PORT_DEFAULT 53248
+#define RTP_UDP_CLI_PORT_DEFAULT 55555
+
+
+#define BUFF_SIZE 4096
+
+#define ID_RIFF 0x46464952
+#define ID_WAVE 0x45564157
+#define ID_FMT  0x20746d66
+#define ID_DATA 0x61746164
+#define FORMAT_PCM 1
+
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+#ifndef TRUE
+#define TRUE 1
+#endif
+
+#ifndef UNUSED
+#define UNUSED(a)    (void)(a)
+#endif
+
+typedef unsigned int uint32; /* Unsigned 32 bit value */
+
+struct riff_wave_header {
+	unsigned int riff_id;
+	unsigned int riff_sz;
+	unsigned int wave_id;
+};
+
+struct chunk_header {
+	unsigned int id;
+	unsigned int sz;
+};
+
+struct chunk_fmt {
+	unsigned short audio_format;
+	unsigned short num_channels;
+	unsigned int sample_rate;
+	unsigned int byte_rate;
+	unsigned short block_align;
+	unsigned short bits_per_sample;
+};
+
+struct wav_header {
+	unsigned int riff_id;
+	unsigned int riff_sz;
+	unsigned int riff_fmt;
+	unsigned int fmt_id;
+	unsigned int fmt_sz;
+	unsigned short audio_format;
+	unsigned short num_channels;
+	unsigned int sample_rate;
+	unsigned int byte_rate;
+	unsigned short block_align;
+	unsigned short bits_per_sample;
+	unsigned int data_id;
+	unsigned int data_sz;
+};
+
+
+#define PCM_WB_BUF_SIZE     640
+#define PCM_NARROW_BUF_SIZE 320
+
+static int record_fd = -1;
+static int send_fd = -1;
+static bool running = FALSE;
+
+
+static void voip_playback_run(void *arg)
+{
+    int rc, len, fd, frames = 0;
+    int pack_size = 320;
+    //char buf[MBTK_PCM_WB_BUF_SIZE];
+    char buf[BUFF_SIZE];
+    char *path = "/data/voip_playback.wav";
+    struct stat st;
+    struct riff_wave_header riff_wave_header;
+    struct chunk_header chunk_header;
+    struct chunk_fmt chunk_fmt = {0};
+    unsigned int more_chunks = 1;
+    uint32 header[4];
+
+    if(send_fd < 0) {
+        printf("Client socket not open.");
+        return;
+    }
+
+    /* Check and open source file */
+    if (access(path, F_OK) || stat(path, &st)) {
+        printf("%s: error reading from file %s\n", __FUNCTION__, path);
+        return;
+    }
+
+    if (!st.st_size) {
+        printf("%s: empty file %s\n", __FUNCTION__, path);
+        return;
+    }
+
+    fd = open(path, O_RDONLY);
+    if (fd < 0) {
+        printf("%s: error opening file %s\n", __FUNCTION__, path);
+        return;
+    }
+
+    lseek(fd, sizeof(struct wav_header), SEEK_SET);
+    uint32 sequence = 1;
+    uint32 timestamp = 0;
+    while (running) {
+        /* Playback loop */
+        memset(buf, 0x00, sizeof(buf));
+        len = read(fd, buf + 16, pack_size);
+        if (len == -1) {
+            printf("%s: error reading from file\n", __FUNCTION__);
+            break;
+        }
+
+        if (len == 0) {
+            /* reached EOF */
+            printf("%s: nothing to read\n", __FUNCTION__);
+            break;
+        }
+
+
+        header[0] = htonl(((uint32_t) 2 << 30) | ((uint32_t) 1 << 24) | ((uint32_t) 0x60 << 16) | ((uint32_t) sequence));
+        header[1] = htonl(timestamp);
+        header[2] = htonl(0xFFFF0000);
+        header[3] = htonl(0xFFFF0000);
+        memcpy(buf, &header, sizeof(header));
+
+        if((rc = sendto(send_fd, buf, len + 16, 0, NULL, 0)) < len + 16) {
+            printf("Send data fail: %d/%d\n", rc, len);
+            break;
+        } else {
+            printf("SEND : %d / %d\n", rc, len);
+        }
+
+        sequence++;
+        timestamp += len / 2;
+
+        ++frames;
+        //printf("%s: No.%d frame playback[len - %d]\n", __FUNCTION__, ++frames, len);
+        usleep(21000);
+    }
+
+    printf("playback_thread exit.\n");
+}
+
+static void sig_handler(int sig)
+{
+    running = FALSE;
+
+    printf("Success exit by signal...\n");
+
+    sleep(1);
+
+    exit(0);
+}
+
+static int rtp_udp_ser_open(const char *local_addr, int local_port)
+{
+    // No set local addr.
+    UNUSED(local_addr);
+
+    int fd = socket(AF_INET, SOCK_DGRAM, 0);
+    if(fd < 0){
+        printf("socket() fail.[%d]\n", errno);
+        return -1;
+    }
+
+    struct sockaddr_in servaddr;
+    memset(&servaddr, 0, sizeof(servaddr));
+    servaddr.sin_family = AF_INET;
+    servaddr.sin_port = htons(local_port);
+    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
+
+    if (bind(fd, (struct sockaddr *)&servaddr, sizeof(struct sockaddr_in)) < 0) {
+        printf("bind() failed: %d\n", errno);
+        goto result_fail_with_close;
+    }
+
+    return fd;
+result_fail_with_close:
+    close(fd);
+    fd = -1;
+    printf("mbtk_sock_open() end:fail\n");
+    return -1;
+}
+
+static int rtp_udp_cli_open(const char *remote_addr, int remote_port)
+{
+    struct sockaddr_in dst_sa4, src_sa4;
+    if (inet_pton(AF_INET, "0.0.0.0", &src_sa4.sin_addr) > 0) {
+        src_sa4.sin_family = AF_INET;
+        src_sa4.sin_port = htons(0);
+        memset(&src_sa4.sin_zero, 0, sizeof(src_sa4.sin_zero));
+    } else {
+        printf("Set src addr fail.\n");
+        return -1;
+    }
+
+    if (inet_pton(AF_INET, remote_addr, &dst_sa4.sin_addr) > 0) {
+        dst_sa4.sin_family = AF_INET;
+        dst_sa4.sin_port = htons(remote_port);
+        memset(&dst_sa4.sin_zero, 0, sizeof(dst_sa4.sin_zero));
+    } else {
+        printf("Set dst addr fail.\n");
+        return -1;
+    }
+
+    int fd = socket(AF_INET, SOCK_DGRAM, 0);
+    if(fd < 0){
+        printf("socket() fail.[%d]\n", errno);
+        return -1;
+    }
+
+    if (bind(fd, (struct sockaddr*) &src_sa4, sizeof(src_sa4)) < 0) {
+        printf("bind() failed: %d\n", errno);
+        goto result_fail_with_close;
+    }
+
+    if (connect(fd, (struct sockaddr*) &dst_sa4, sizeof(dst_sa4)) < 0) {
+        printf("connect() failed: %d\n", errno);
+        goto result_fail_with_close;
+    }
+
+#if 0
+    if(socket_noblock(fd)) {
+        goto result_fail_with_close;
+    }
+#endif
+
+    return fd;
+result_fail_with_close:
+    close(fd);
+    fd = -1;
+    printf("mbtk_sock_open() end:fail\n");
+    return -1;
+}
+
+int main(int argc, char *argv[])
+{
+    if(argc != 2) {
+        printf("mbtk_rtp_udp_cli <IP>\n");
+        return -1;
+    }
+
+    // mbtk_log_init("radio", "RTP_TEST");
+
+    signal(SIGINT, sig_handler);
+    signal(SIGTERM, sig_handler);
+
+
+    int ser_fd = rtp_udp_ser_open(NULL, RTP_UDP_SER_PORT_DEFAULT);
+    if(ser_fd < 0) {
+        printf("rtp_udp_ser_open() fail.\n");
+        return -1;
+    }
+
+    send_fd = rtp_udp_cli_open(argv[1], RTP_UDP_CLI_PORT_DEFAULT);
+    if(send_fd < 0) {
+        printf("rtp_udp_cli_open() fail.\n");
+        // return -1;
+    }
+
+    struct wav_header header;
+    int rc = 0;
+    char *path = "/data/voip_record.wav";
+
+    header.riff_id = ID_RIFF;
+    header.riff_sz = 0;
+    header.riff_fmt = ID_WAVE;
+    header.fmt_id = ID_FMT;
+    header.fmt_sz = 16;
+    header.audio_format = 1;        //FORMAT_PCM;
+    header.num_channels = 1;        //Modem ONLY support mono recording
+    header.sample_rate = 8000;
+    header.bits_per_sample = 16;    //PCM_SAMPLEBITS_S16_LE;
+    header.byte_rate = (header.bits_per_sample / 8) * header.num_channels * header.sample_rate;
+    header.block_align = header.num_channels * (header.bits_per_sample / 8);
+    header.data_id = ID_DATA;
+
+    record_fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, 0644);
+    if (record_fd < 0) {
+        printf("%s: error opening file %s!\n", __FUNCTION__, path);
+        return -1;
+    }
+
+    lseek(record_fd, 0, SEEK_SET);
+    write(record_fd, &header, sizeof(struct wav_header));
+
+    //leave enough room for header
+    lseek(record_fd, sizeof(struct wav_header), SEEK_SET);
+
+    char buff[2048];
+    int len_recv;
+    int len_send;
+    running = TRUE;
+    bool is_first = TRUE;
+    while(running) {
+        len_recv = recvfrom(ser_fd, buff, sizeof(buff), 0, NULL, NULL);
+        if(len_recv < 0) {
+            printf("recvfrom() ret is %d,errno - %d\n", len_recv, errno);
+            continue;
+        } else if(len_recv == 0) {
+            printf("ret is 0\n");
+        } else if(len_recv > 16){
+            printf("RECV:len - %d\n", len_recv);
+            write(record_fd, buff + 16, len_recv - 16);
+
+            if(is_first) {
+                pthread_t playabck_thread/*, record_thread*/;
+                rc = pthread_create(&playabck_thread, NULL, (void *)&voip_playback_run, NULL);
+                if (rc < 0) {
+                    printf("error creating thread_start!");
+                    break;
+                }
+                is_first = FALSE;
+            }
+
+#if 0
+            if(cli_fd < 0) {
+                cli_fd = rtp_udp_cli_open(argv[1], RTP_UDP_CLI_PORT_DEFAULT);
+                if(cli_fd < 0) {
+                    printf("rtp_udp_cli_open() fail.\n");
+                    // return -1;
+                } else {
+                    printf("rtp_udp_cli_open() success.\n");
+                }
+            }
+
+            if(cli_fd > 0) {
+                len_send = sendto(cli_fd, buff, len_recv, 0, NULL, 0);
+                printf("SEND : %d / %d\n", len_send, len_recv);
+            }
+#endif
+        } else {
+            printf("RTP Header error.\n");
+        }
+    }
+
+    close(record_fd);
+
+    close(ser_fd);
+
+    return 0;
+}
+
+