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