blob: 4ae8a74aeea4a77a6b14d7626f0125eca81cd242 [file] [log] [blame]
b.liuf191eb72024-12-12 10:45:23 +08001/*
2* rtp_server.c
3*
4* RTP transport service.
5*
6* -------------------------
7* | |
8* ------ UDP | ------- |
9* | | -----|-> playback -> | | |
10* | MCU | | | Voice | |
11* | | UDP | | | |
12* ------ <----|-- record <--- | | |
13* | ------- |
14* -------------------------
15*/
16/******************************************************************************
17
18 EDIT HISTORY FOR FILE
19
20 WHEN WHO WHAT,WHERE,WHY
21-------- -------- -------------------------------------------------------
222024/12/3 LiuBin Initial version
23
24******************************************************************************/
25#include <stdio.h>
26#include <errno.h>
27#include <pthread.h>
28#include <stdlib.h>
29#include <unistd.h>
30#include <fcntl.h>
31#include <sys/types.h>
32#include <sys/socket.h>
33#include <sys/un.h>
34#include <netinet/in.h>
35#include <sys/epoll.h>
36#include <arpa/inet.h>
37#include <sys/ioctl.h>
38#include <sys/time.h>
39
40#include "mbtk_log.h"
41#include "mbtk_utils.h"
42#include "mbtk_audio2.h"
43#include "mbtk_rtp_internal.h"
44
45#define RTP_DEBUG_PCM_FILE 1
46#define RTP_UDP_READ_BUFF_SIZE 2048
47
48static rtp_udp_ser_state_enum udp_state = RTP_UDP_SER_STATE_IDEL;
49static rtp_voip_ser_state_enum voip_state = RTP_VOIP_SER_STATE_IDEL;
50extern rtp_info_t rtp_info;
51static pthread_t voip_playback;
52
53static rtp_header_info_t rtp_head = {
54 .version = 2, // 2 (2 bit)
55 .padding = 0, // 0 (1 bit)
56 .extension = 0, // 0 (1 bit)
57 .csrc = 1, // 1 (4 bit)
58 .marker = 0, // 0 (1 bit)
59 .payload_type = 0x60, // 0x60 (7 bit)
60 .sequence = 0, // (16 bit)
61 .timestamp = 0, // (32 bit)
62 .ssrc = 0xFFFF0000, // 0xFFFF0000 (32 bit)
63 .csrc = 0xFFFF0000 // 0xFFFF0000 (32 bit)
64};
65
66int epoll_fd_add(int fd);
67int epoll_fd_del(int fd);
68
69static void *mbtk_memcpy(const void *src, unsigned int n)
70{
71 void *dest = malloc(n);
72 if(dest) {
73 return memcpy(dest, src, n);
74 } else {
75 return NULL;
76 }
77}
78
79static void rtp_send_init()
80{
81 rtp_info.send.iov_idx = 1; // First is RTP header.
82 rtp_info.send.pack_size = 0;
83 rtp_info.send.remain_buff_len = 0;
84 rtp_info.recv.first_packet = TRUE;
85
86 if(rtp_info.recv.recv_buff == NULL)
87 rtp_info.recv.recv_buff = mbtk_loopbuff_get(1024 * 1024);
88
89 rtp_head.sequence = (uint32) (rand()*rand());
90 rtp_head.timestamp = 0;
91}
92
93static int rtp_pack_push(const uint8 *data, uint32 data_len, uint32_t timestamp)
94{
95 UNUSED(data);
96 UNUSED(data_len);
97 UNUSED(timestamp);
98
99 if(rtp_info.recv.recv_buff) {
100 if(data_len != mbtk_loopbuff_write(rtp_info.recv.recv_buff, data, data_len))
101 return -1;
102 }
103 return 0;
104}
105
106static void udp_read_cb(int fd)
107{
108 int size;
109 size_t audio_length;
110 size_t metadata_length;
111 struct msghdr m;
112 //struct cmsghdr *cm;
113 struct iovec iov;
114 uint32_t header;
115 uint32_t ssrc;
116 uint8_t payload;
117 unsigned cc;
118 ssize_t r;
119 uint8_t aux[1024];
120 //bool found_tstamp = false;
121 uint32_t timestamp;
122 int64_t k, j, delta;
123
124 uint8_t recv_buf[RTP_UDP_READ_BUFF_SIZE];
125 //size_t recv_buf_size = 0;
126
127 if (ioctl(fd, FIONREAD, &size) < 0) {
128 LOGE("FIONREAD failed: %d", errno);
129 goto fail;
130 }
131
132 if (size <= 0) {
133 /* size can be 0 due to any of the following reasons:
134 *
135 * 1. Somebody sent us a perfectly valid zero-length UDP packet.
136 * 2. Somebody sent us a UDP packet with a bad CRC.
137 *
138 * It is unknown whether size can actually be less than zero.
139 *
140 * In the first case, the packet has to be read out, otherwise the
141 * kernel will tell us again and again about it, thus preventing
142 * reception of any further packets. So let's just read it out
143 * now and discard it later, when comparing the number of bytes
144 * received (0) with the number of bytes wanted (1, see below).
145 *
146 * In the second case, recvmsg() will fail, thus allowing us to
147 * return the error.
148 *
149 * Just to avoid passing zero-sized memchunks and NULL pointers to
150 * recvmsg(), let's force allocation of at least one byte by setting
151 * size to 1.
152 */
153 size = 1;
154 }
155
156 iov.iov_base = recv_buf;
157 iov.iov_len = (size_t) size;
158
159 m.msg_name = NULL;
160 m.msg_namelen = 0;
161 m.msg_iov = &iov;
162 m.msg_iovlen = 1;
163 m.msg_control = aux;
164 m.msg_controllen = sizeof(aux);
165 m.msg_flags = 0;
166
167 r = recvmsg(fd, &m, 0);
168
169 if (r != size) {
170 if (r < 0 && errno != EAGAIN && errno != EINTR)
171 LOGE("recvmsg() failed: %s", r < 0 ? strerror(errno) : "size mismatch");
172
173 goto fail;
174 }
175
176 if(voip_state != RTP_VOIP_SER_STATE_RUNNING) {
177 return;
178 }
179
180#if 0
181 printf("RECV : %d\n", r);
182
183 int send_len = mbtk_audio_pcm_play_data_send(recv_buf, r);
184 if(r != send_len) {
185 printf("play_data_send fail: %d/%d\n", send_len, r);
186 }
187#endif
188 if (size < 12) {
189 LOGE("RTP packet too short.");
190 goto fail;
191 }
192
193#if 1
194 memcpy(&header, iov.iov_base, sizeof(uint32_t));
195 memcpy(&timestamp, (uint8_t*) iov.iov_base + 4, sizeof(uint32_t));
196 memcpy(&ssrc, (uint8_t*) iov.iov_base + 8, sizeof(uint32_t));
197
198 header = ntohl(header);
199 timestamp = ntohl(timestamp);
200 ssrc = ntohl(ssrc);
201
202 if ((header >> 30) != 2) {
203 LOGE("Unsupported RTP version.");
204 goto fail;
205 }
206
207 if ((header >> 29) & 1) {
208 LOGE("RTP padding not supported.");
209 goto fail;
210 }
211
212 if ((header >> 28) & 1) {
213 LOGE("RTP header extensions not supported.");
214 goto fail;
215 }
216
217 if (ssrc != rtp_head.ssrc) {
218 LOGE("Got unexpected SSRC");
219 goto fail;
220 }
221
222 cc = (header >> 24) & 0xF;
223 payload = (uint8_t) ((header >> 16) & 127U);
224 rtp_head.sequence = (uint16_t) (header & 0xFFFFU);
225
226 metadata_length = 12 + cc * 4;
227
228 if (payload != rtp_head.payload_type) {
229 LOGE("Got unexpected payload: %u", payload);
230 goto fail;
231 }
232
233 if (metadata_length > (unsigned) size) {
234 LOGE("RTP packet too short. (CSRC)");
235 goto fail;
236 }
237
238 audio_length = size - metadata_length;
239
240 if (audio_length % rtp_info.frame_size != 0) {
241 LOGE("Bad RTP packet size.");
242 goto fail;
243 }
244
245 if (rtp_info.recv.first_packet) {
246 rtp_info.recv.first_packet = FALSE;
247 rtp_info.recv.offset = timestamp;
248 }
249
250 /* Check whether there was a timestamp overflow */
251 k = (int64_t) timestamp - (int64_t) rtp_info.recv.offset;
252 j = (int64_t) 0x100000000LL - (int64_t) rtp_info.recv.offset + (int64_t) timestamp;
253
254 if ((k < 0 ? -k : k) < (j < 0 ? -j : j))
255 delta = k;
256 else
257 delta = j;
258
259 LOGD("RECV : %d, delta = %d", audio_length, delta);
260// pa_memblockq_seek(s->memblockq, delta * (int64_t) rtp_info.frame_size, PA_SEEK_RELATIVE, true);
261
262 /* The next timestamp we expect */
263 rtp_info.recv.offset = timestamp + (uint32_t) (audio_length / rtp_info.frame_size);
264
265
266 if(rtp_pack_push(recv_buf + metadata_length, audio_length, timestamp)) {
267 LOGE("rtp_pack_push() fail.");
268 }
269
270#endif
271
272 return;
273
274fail:
275
276 return;
277}
278
279static void voip_recorder_cb(void *data, uint32 data_len)
280{
281 if(data_len > 0) {
282 LOGD("Record : %d", data_len);
283 if(rtp_info.udp_send_sock.fd > 0) {
284#if 0
285 int len = sendto(rtp_info.udp_send_sock.fd, data, data_len, 0, NULL, 0);
286 printf("SEND : %d / %d\n", len, data_len);
287#else
288 // 有剩余数据
289 if(rtp_info.send.iov_idx == 1 && rtp_info.send.remain_buff_len > 0) {
290 rtp_info.send.iov[rtp_info.send.iov_idx].iov_base = mbtk_memcpy(rtp_info.send.remain_buff,
291 rtp_info.send.remain_buff_len);
292 rtp_info.send.iov[rtp_info.send.iov_idx].iov_len = rtp_info.send.remain_buff_len;
293 rtp_info.send.iov_idx++;
294
295 rtp_info.send.pack_size += rtp_info.send.remain_buff_len;
296 rtp_info.send.remain_buff_len = 0;
297 }
298
299 // UDP各分包总大小不超过 c->mtu ( 默认: DEFAULT_MTU )
300 // k 为分包大小
301 uint32 k = rtp_info.send.pack_size + data_len > rtp_info.send.mtu ?
302 rtp_info.send.mtu - rtp_info.send.pack_size : data_len;
303
304 rtp_info.send.iov[rtp_info.send.iov_idx].iov_base = mbtk_memcpy(data, k);
305 rtp_info.send.iov[rtp_info.send.iov_idx].iov_len = k;
306 rtp_info.send.iov_idx++;
307
308 rtp_info.send.pack_size += k;
309
310 if(rtp_info.send.pack_size % rtp_info.frame_size != 0) {
311 LOGW("pack size error: %d - %d", rtp_info.send.pack_size, rtp_info.frame_size);
312 return;
313 }
314
315 if (rtp_info.send.pack_size >= rtp_info.send.mtu || rtp_info.send.iov_idx >= MAX_IOVECS) {
316 uint32_t header[4];
317 struct msghdr m;
318 ssize_t k;
319 int i;
320
321 header[0] = htonl(((uint32_t) rtp_head.version << 30) | ((uint32_t) rtp_head.csrc_count << 24) | ((uint32_t) rtp_head.payload_type << 16) | ((uint32_t) rtp_head.sequence));
322 header[1] = htonl(rtp_head.timestamp);
323 header[2] = htonl(rtp_head.ssrc);
324 header[3] = htonl(rtp_head.csrc);
325
326 rtp_info.send.iov[0].iov_base = (void*)header;
327 rtp_info.send.iov[0].iov_len = sizeof(header);
328
329 m.msg_name = NULL;
330 m.msg_namelen = 0;
331 m.msg_iov = rtp_info.send.iov;
332 m.msg_iovlen = (size_t) rtp_info.send.iov_idx;
333 m.msg_control = NULL;
334 m.msg_controllen = 0;
335 m.msg_flags = 0;
336
337 k = sendmsg(rtp_info.udp_send_sock.fd, &m, MSG_DONTWAIT);
338
339 for (i = 1; i < rtp_info.send.iov_idx; i++) {
340 free(rtp_info.send.iov[i].iov_base);
341 rtp_info.send.iov[i].iov_base = NULL;
342 }
343
344 rtp_head.sequence++;
345
346 // 时间单位转为帧数(每帧多少us)
347 rtp_head.timestamp += (unsigned) (rtp_info.send.pack_size / rtp_info.frame_size);
348
349 if (k < 0) {
350 if (errno != EAGAIN && errno != EINTR) /* If the queue is full, just ignore it */
351 LOGE("sendmsg() failed: %s", strerror(errno));
352 return;
353 }
354
355 rtp_info.send.pack_size = 0;
356 rtp_info.send.iov_idx = 1;
357 }
358#endif
359 }
360 } else {
361 LOGD("Recorver data end.");
362 }
363}
364
365static int64 time_us_get()
366{
367 struct timespec ts;
368 memset(&ts, 0, sizeof(struct timespec));
369
370 if(clock_gettime(CLOCK_REALTIME, &ts)) {
371 LOGE("clock_gettime() fail:%d", errno);
372 return -1;
373 }
374
375 return ts.tv_sec * 1000000 + ts.tv_nsec / 1000;
376}
377
378static void voip_playback_thread(void *arg)
379{
380 UNUSED(arg);
381 char *buff = (char*)malloc(rtp_info.playback_size * 2);
382 if(buff == NULL) {
383 LOGE("malloc() fail.");
384 return;
385 }
386
387 if(mbtk_audio_voice_pcm_playback_start()) {
388 LOGE("mbtk_audio_voice_pcm_playback_start() fail.");
389 return;
390 }
391
392 usleep(100000);
393
394 int64 play_start = time_us_get(); // us
395 //uint64 play_count = 0;
396 //char num_buff[1024] = {0};
397 while (voip_state == RTP_VOIP_SER_STATE_RUNNING) {
398 int len;
399 if((len = mbtk_loopbuff_read(rtp_info.recv.recv_buff, buff, rtp_info.playback_size * 2)) > 0) {
400 int send_len = mbtk_audio_pcm_play_data_send(buff, len);
401 if(send_len > 0) {
402 if(len != send_len) {
403 LOGW("play_data_send fail: %d/%d\n", send_len, len);
404 }
405 //play_count += send_len;
406 int64 play_now = time_us_get();
407 int time_offset = (int)((play_now - play_start) / 1000 * rtp_info.sample_for_ms);
408 LOGD("loopbuff:%d, time_offset:%d, send_len:%d", mbtk_loopbuff_size(rtp_info.recv.recv_buff), time_offset,
409 send_len / 2);
410#if 0
411 int offset = send_len / 2 - time_offset;
412 if(offset < 0 && len > -offset * 2) {
413#if 0
414 if(mbtk_loopbuff_seek(rtp_info.recv.recv_buff, offset * 2)) {
415 LOGE("mbtk_loopbuff_seek() fail.");
416 }
417 mbtk_loopbuff_print(rtp_info.recv.recv_buff);
418#else
419 mbtk_audio_pcm_play_data_send(buff + len + offset * 2, -offset * 2);
420#endif
421 }
422#endif
423 play_start = play_now;
424 }
425 }
426#if 0
427 else {
428 if(voip_state == RTP_VOIP_SER_STATE_RUNNING)
429 usleep(5000);
430 }
431 // LOGD("%s: No.%d frame playback.", __FUNCTION__, ++frames);
432
433 int time_offset = (int)((time_us_get() - play_start) / 1000 * rtp_info.sample_for_ms);
434 LOGD("loopbuff:%d, time_offset:%d, play_count:%d", mbtk_loopbuff_size(rtp_info.recv.recv_buff), time_offset,
435 play_count / 2);
436#endif
437 }
438
439 if(mbtk_audio_pcm_play_stop()) {
440 LOGE("mbtk_audio_pcm_play_stop() fail.");
441 return;
442 }
443
444 free(buff);
445 return;
446}
447
448
449static int udp_setsockopt(int fd)
450{
451 int priority = 6;
452 if (setsockopt(fd, SOL_SOCKET, SO_PRIORITY, (const void *) &priority, sizeof(priority)) < 0) {
453 LOGE("setsockopt(SO_PRIORITY) fail:errno - %d", errno);
454 return -1;
455 }
456
457 int one = 1;
458 if (setsockopt(fd, SOL_SOCKET, SO_TIMESTAMP, &one, sizeof(one)) < 0) {
459 LOGE("SO_TIMESTAMP failed: %d", errno);
460 return -1;
461 }
462
463 one = 1;
464 if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)) < 0) {
465 LOGE("SO_REUSEADDR failed: %d", errno);
466 return -1;
467 }
468
469 return 0;
470}
471
472static int socket_noblock(int fd)
473{
474 // Set O_NONBLOCK
475 int flags = fcntl(fd, F_GETFL, 0);
476 if (flags < 0)
477 {
478 LOGE("Get flags error:%d", errno);
479 return -1;
480 }
481 flags |= O_NONBLOCK;
482 if (fcntl(fd, F_SETFL, flags) < 0)
483 {
484 LOGE("Set flags error:%d", errno);
485 return -1;
486 }
487
488 return 0;
489}
490
491static int rtp_udp_ser_open(const char *local_addr, int local_port)
492{
493 // No set local addr.
494 UNUSED(local_addr);
495
496 int fd = socket(AF_INET, SOCK_DGRAM, 0);
497 if(fd < 0){
498 LOGE("socket() fail.[%d]", errno);
499 return -1;
500 }
501
502 if(udp_setsockopt(fd)) {
503 goto result_fail_with_close;
504 }
505
506 struct sockaddr_in servaddr;
507 memset(&servaddr, 0, sizeof(servaddr));
508 servaddr.sin_family = AF_INET;
509 servaddr.sin_port = htons(local_port);
510 servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
511
512 if (bind(fd, (struct sockaddr *)&servaddr, sizeof(struct sockaddr_in)) < 0) {
513 LOGE("bind() failed: %d", errno);
514 goto result_fail_with_close;
515 }
516
517 return fd;
518result_fail_with_close:
519 close(fd);
520 fd = -1;
521 LOGE("mbtk_sock_open() end:fail");
522 return -1;
523}
524
525static int rtp_udp_cli_open(const char *remote_addr, int remote_port)
526{
527 struct sockaddr_in dst_sa4, src_sa4;
528 if (inet_pton(AF_INET, "0.0.0.0", &src_sa4.sin_addr) > 0) {
529 src_sa4.sin_family = AF_INET;
530 src_sa4.sin_port = htons(0);
531 memset(&src_sa4.sin_zero, 0, sizeof(src_sa4.sin_zero));
532 } else {
533 LOGE("Set src addr fail.");
534 return -1;
535 }
536
537 if (inet_pton(AF_INET, remote_addr, &dst_sa4.sin_addr) > 0) {
538 dst_sa4.sin_family = AF_INET;
539 dst_sa4.sin_port = htons(remote_port);
540 memset(&dst_sa4.sin_zero, 0, sizeof(dst_sa4.sin_zero));
541 } else {
542 LOGE("Set dst addr fail.");
543 return -1;
544 }
545
546 int fd = socket(AF_INET, SOCK_DGRAM, 0);
547 if(fd < 0){
548 LOGE("socket() fail.[%d]", errno);
549 return -1;
550 }
551
552 if (bind(fd, (struct sockaddr*) &src_sa4, sizeof(src_sa4)) < 0) {
553 LOGE("bind() failed: %d", errno);
554 goto result_fail_with_close;
555 }
556
557 if (connect(fd, (struct sockaddr*) &dst_sa4, sizeof(dst_sa4)) < 0) {
558 LOGE("connect() failed: %d", errno);
559 goto result_fail_with_close;
560 }
561
562 if(socket_noblock(fd)) {
563 goto result_fail_with_close;
564 }
565
566 if(udp_setsockopt(fd)) {
567 goto result_fail_with_close;
568 }
569
570 return fd;
571result_fail_with_close:
572 close(fd);
573 fd = -1;
574 LOGE("mbtk_sock_open() end:fail");
575 return -1;
576}
577
578
579/*===========================================================================
580FUNCTION rtp_udp_server_start
581
582DESCRIPTION:
583 Start RTP UDP server,will monitor rtp packet from MCU.
584
585PARAMETERS:
586 conf_info : RTP config informations.
587
588RETURN VALUE:
589 int : 0 for success, other for fail.
590
591===========================================================================*/
592int rtp_udp_server_start(rtp_config_t *conf_info)
593{
594 UNUSED(conf_info);
595 if(udp_state != RTP_UDP_SER_STATE_IDEL) {
596 LOGE("udp_state error : %d", udp_state);
597 return -1;
598 }
599
600 udp_state = RTP_UDP_SER_STATE_STARTING;
601 rtp_info.frame_size = conf_info->channel * RTP_SAMPLE_NUMBER;
602 rtp_info.send.mtu = (RTP_DEFAULT_MTU / rtp_info.frame_size) * rtp_info.frame_size;
603 if(conf_info->sample_rate == MBTK_AUDIO_SAMPLE_RATE_8000) {
604 rtp_info.playback_size = MBTK_PCM_NB_BUF_SIZE;
605 rtp_info.sample_for_ms = 8;
606 } else {
607 rtp_info.playback_size = MBTK_PCM_WB_BUF_SIZE;
608 rtp_info.sample_for_ms = 16;
609 }
610 LOGD("frame_size = %d, MTU = %d", rtp_info.frame_size, rtp_info.send.mtu);
611
612 // Open UDP server socket.
613 LOGD("Start open UDP server : NULL-%d", conf_info->client_port);
614 rtp_info.udp_recv_sock.fd = rtp_udp_ser_open(NULL, conf_info->client_port);
615 if(rtp_info.udp_recv_sock.fd < 0) {
616 LOGE("socket(udp_recv_sock) fail : errno = %d", errno);
617 goto fail;
618 }
619 rtp_info.udp_recv_sock.read_cb = udp_read_cb;
620 socket_noblock(rtp_info.udp_recv_sock.fd);
621 epoll_fd_add(rtp_info.udp_recv_sock.fd);
622
623#if 0
624 rtp_info.udp_send_sock.fd = rtp_udp_cli_open(conf_info->remote_ip, conf_info->server_port);
625 if(rtp_info.udp_send_sock.fd < 0) {
626 LOGW("socket(udp_send_sock) fail : errno = %d", errno);
627 LOGW("Can not connected to %s:%d.", conf_info->remote_ip, conf_info->server_port);
628 // goto fail;
629 }
630 rtp_info.udp_send_sock.read_cb = NULL;
631#endif
632
633 udp_state = RTP_UDP_SER_STATE_RUNNING;
634
635 LOGD("UDP server is running...");
636 return 0;
637
638fail:
639 if(rtp_info.udp_recv_sock.fd > 0) {
640 epoll_fd_del(rtp_info.udp_recv_sock.fd);
641 close(rtp_info.udp_recv_sock.fd);
642 rtp_info.udp_recv_sock.fd = -1;
643 rtp_info.udp_recv_sock.read_cb = NULL;
644 }
645
646#if 0
647 if(rtp_info.udp_send_sock.fd > 0) {
648 close(rtp_info.udp_send_sock.fd);
649 rtp_info.udp_send_sock.fd = -1;
650 rtp_info.udp_send_sock.read_cb = NULL;
651 }
652#endif
653
654 udp_state = RTP_UDP_SER_STATE_IDEL;
655 return -1;
656}
657
658/*===========================================================================
659FUNCTION rtp_udp_server_stop
660
661DESCRIPTION:
662 Stop RTP UDP server.
663
664PARAMETERS:
665 Non.
666
667RETURN VALUE:
668 int : 0 for success, other for fail.
669
670===========================================================================*/
671int rtp_udp_server_stop()
672{
673 if(udp_state != RTP_UDP_SER_STATE_RUNNING) {
674 LOGE("udp_state error : %d", udp_state);
675 return -1;
676 }
677
678 udp_state = RTP_UDP_SER_STATE_STOPING;
679 if(rtp_info.udp_recv_sock.fd > 0) {
680 epoll_fd_del(rtp_info.udp_recv_sock.fd);
681
682 close(rtp_info.udp_recv_sock.fd);
683 rtp_info.udp_recv_sock.fd = -1;
684 rtp_info.udp_recv_sock.read_cb = NULL;
685 }
686
687#if 0
688 if(rtp_info.udp_send_sock.fd > 0) {
689 close(rtp_info.udp_send_sock.fd);
690 rtp_info.udp_send_sock.fd = -1;
691 rtp_info.udp_send_sock.read_cb = NULL;
692 }
693#endif
694
695 udp_state = RTP_UDP_SER_STATE_IDEL;
696
697 return 0;
698}
699
700
701/*===========================================================================
702FUNCTION rtp_voip_server_start
703
704DESCRIPTION:
705 Start RTP voip server.will start playback/record PCM to/from voice path.
706
707PARAMETERS:
708 conf_info : RTP config informations.
709
710RETURN VALUE:
711 int : 0 for success, other for fail.
712
713===========================================================================*/
714int rtp_voip_server_start(const rtp_config_t *conf_info)
715{
716 UNUSED(conf_info);
717 if(voip_state != RTP_VOIP_SER_STATE_IDEL) {
718 LOGE("voip_state error : %d", voip_state);
719 return -1;
720 }
721
722 voip_state = RTP_VOIP_SER_STATE_STARTING;
723 if(mbtk_audio_pcm_init()) {
724 LOGE("mbtk_audio_pcm_init() fail.");
725 voip_state = RTP_VOIP_SER_STATE_IDEL;
726 }
727
728 LOGD("Start open UDP client : %s-%d", conf_info->remote_ip, conf_info->server_port);
729 rtp_info.udp_send_sock.fd = rtp_udp_cli_open(conf_info->remote_ip, conf_info->server_port);
730 if(rtp_info.udp_send_sock.fd < 0) {
731 LOGE("Can not connected to %s:%d [errno-%d].", conf_info->remote_ip, conf_info->server_port, errno);
732 goto error;
733 }
734 rtp_info.udp_send_sock.read_cb = NULL;
735
736 rtp_send_init();
737
738 if(mbtk_audio_voice_pcm_record_start(voip_recorder_cb)) {
739 LOGE("mbtk_audio_voice_pcm_record_start() fail.");
740 goto error;
741 }
742
743 voip_state = RTP_VOIP_SER_STATE_RUNNING;
744
745 pthread_attr_t thread_attr;
746 pthread_attr_init(&thread_attr);
747 if(pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED))
748 {
749 LOGE("pthread_attr_setdetachstate() fail.");
750 goto error;
751 }
752
753 if (pthread_create(&voip_playback, NULL, (void *)&voip_playback_thread, NULL) < 0) {
754 LOGE("%s: error creating thread_recorder!", __FUNCTION__);
755 goto error;
756 }
757
758 LOGD("VOIP server is running...");
759 return 0;
760error:
761 if(mbtk_audio_pcm_deinit()) {
762 LOGE("mbtk_audio_pcm_deinit() fail.");
763 }
764
765 if(rtp_info.udp_send_sock.fd > 0) {
766 close(rtp_info.udp_send_sock.fd);
767 rtp_info.udp_send_sock.fd = -1;
768 rtp_info.udp_send_sock.read_cb = NULL;
769 }
770
771 voip_state = RTP_VOIP_SER_STATE_IDEL;
772 return -1;
773}
774
775
776/*===========================================================================
777FUNCTION rtp_server_stop
778
779DESCRIPTION:
780 Stop RTP voip server.
781
782PARAMETERS:
783 Non.
784
785RETURN VALUE:
786 int : 0 for success, other for fail.
787
788===========================================================================*/
789int rtp_voip_server_stop()
790{
791 if(voip_state != RTP_VOIP_SER_STATE_RUNNING) {
792 LOGE("voip_state error : %d", voip_state);
793 return -1;
794 }
795
796 voip_state = RTP_VOIP_SER_STATE_STOPING;
797#if 0
798 if(mbtk_audio_pcm_play_stop()) {
799 LOGE("mbtk_audio_pcm_play_stop() fail.");
800 return -1;
801 }
802#else
803 if (pthread_join(voip_playback, NULL)) {
804 LOGE("error join voip_playback!");
805 return -1;
806 }
807#endif
808
809 if(mbtk_audio_pcm_recorder_stop()) {
810 LOGE("mbtk_audio_pcm_recorder_stop() fail.");
811 return -1;
812 }
813
814 if(mbtk_audio_pcm_deinit()) {
815 LOGE("mbtk_audio_pcm_deinit() fail.");
816 return -1;
817 }
818
819 if(rtp_info.recv.recv_buff) {
820 mbtk_loopbuff_free(rtp_info.recv.recv_buff);
821 rtp_info.recv.recv_buff = NULL;
822 }
823
824 voip_state = RTP_VOIP_SER_STATE_IDEL;
825
826 return 0;
827}
828