mptsd reads mpegts streams from udp/multicast or http and combines them into one multiple program stream that is suitable for outputting to DVB-C modulator. Tested with Dektec DTE-3114 Quad QAM Modulator and used in production in small DVB-C networks. https://georgi.unixsol.org/programs/mptsd/
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

udp_server.c 3.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. /*
  2. * mptsd internal web server
  3. * Copyright (C) 2010-2011 Unix Solutions Ltd.
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License version 2
  7. * as published by the Free Software Foundation.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program; if not, write to the Free Software
  16. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
  17. */
  18. #include <stdlib.h>
  19. #include <regex.h>
  20. #include <errno.h>
  21. #include <string.h>
  22. #include <signal.h>
  23. #include <arpa/inet.h>
  24. #include <netinet/in.h>
  25. #include "libfuncs/libfuncs.h"
  26. #include "libfuncs/io.h"
  27. #include "libfuncs/log.h"
  28. #include "libtsfuncs/tsfuncs.h"
  29. #include "data.h"
  30. #include "config.h"
  31. #include "network.h"
  32. #include "udp_server.h"
  33. extern int keep_going;
  34. #define NEXT_CLIENT { FREE(path); FREE(buf); pthread_exit(0); }
  35. #define SHUTDOWN_CLIENT { FREE(path); FREE(buf); shutdown_fd(&clientsock); pthread_exit(0); }
  36. #define BUFSIZE 1316
  37. void *udp_server_thread(void *data) {
  38. CONFIG *conf = data;
  39. struct sockaddr_in client; /* remote address */
  40. socklen_t clientlen = sizeof(client); /* length of addresses */
  41. int clientsock; /* #bytes received */
  42. char buf[FRAME_PACKET_SIZE]; /* receive buffer */
  43. while (keep_going) {
  44. clientsock = recvfrom(conf->udp_server_socket,(char*)buf, FRAME_PACKET_SIZE, 0, (struct sockaddr *)&client, &clientlen);
  45. if (clientsock < 0) {
  46. if (conf->udp_server_socket > -1) // The server_socket is closed on exit, so do not report errors
  47. LOGf("ERROR : Failed to accept client fd: %i err: %s\n", clientsock, strerror(errno));
  48. if (errno==EMFILE || errno==ENFILE)
  49. break;
  50. } else {
  51. // LOGf("received %d bytes from %s with port %d \n", clientsock, inet_ntoa(client.sin_addr), ntohs( client.sin_port ) );
  52. // TODO Process buffer and add to output_mix
  53. }
  54. }
  55. pthread_exit(0);
  56. }
  57. void udp_server_start(CONFIG *conf) {
  58. if (conf->udp_server_port)
  59. udp_server_init(conf->udp_server_addr, conf->udp_server_port, &conf->udp_server, &conf->udp_server_socket);
  60. if (conf->udp_server_socket > -1) {
  61. LOG("UDP_SERVER: Started \n");
  62. pthread_create(&conf->udp_server_thread, NULL, &udp_server_thread, conf);
  63. }
  64. }
  65. void udp_server_stop(CONFIG *conf) {
  66. if (conf->udp_server_socket > -1) {
  67. shutdown_fd(&conf->udp_server_socket);
  68. pthread_join(conf->udp_server_thread, NULL);
  69. }
  70. }
  71. void udp_server_init(char *bind_addr, int bind_port, struct sockaddr_in *server, int *server_socket) {
  72. LOG("UDP_SERVER: Init.\n");
  73. char *binded;
  74. struct hostent *host_ptr;
  75. *server_socket = socket(PF_INET, SOCK_DGRAM, 0);
  76. if (*server_socket == -1) {
  77. perror("socket(server_socket)");
  78. exit(1);
  79. }
  80. int j = 1;
  81. if (setsockopt(*server_socket, SOL_SOCKET, SO_REUSEADDR,(const char *) &j, sizeof(j))<0) {
  82. perror("setsockopt(SO_REUSEADDR)");
  83. exit(1);
  84. }
  85. memset(server, 0, sizeof(struct sockaddr_in));
  86. if (!bind_addr) {
  87. binded = "*";
  88. server->sin_addr.s_addr = htonl(INADDR_ANY);
  89. } else {
  90. host_ptr = gethostbyname(bind_addr);
  91. if (!host_ptr) {
  92. fprintf(stderr,"Error can't resolve bind address: %s\n", bind_addr);
  93. exit(1);
  94. }
  95. memcpy(&server->sin_addr, host_ptr->h_addr, sizeof(server->sin_addr));
  96. binded = inet_ntoa(server->sin_addr);
  97. }
  98. /* Bind to server socket */
  99. LOGf ("UDP_SERVER: Bind to : %s:%i\n", binded, bind_port);
  100. server->sin_family = AF_INET;
  101. server->sin_port = htons(bind_port);
  102. if (bind(*server_socket, (struct sockaddr *)server, sizeof(struct sockaddr_in)) < 0) {
  103. perror("bind(server_socket)");
  104. exit(1);
  105. }
  106. LOG("UDP_SERVER: UDP server Initialized.\n");
  107. }