streamplayer.c 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. /*
  2. * Asterisk -- An open source telephony toolkit.
  3. *
  4. * Copyright (C) 1999 - 2005, Digium, Inc.
  5. *
  6. * Russell Bryant <russell@digium.com>
  7. *
  8. * See http://www.asterisk.org for more information about
  9. * the Asterisk project. Please do not directly contact
  10. * any of the maintainers of this project for assistance;
  11. * the project provides a web site, mailing lists and IRC
  12. * channels for your use.
  13. *
  14. * This program is free software, distributed under the terms of
  15. * the GNU General Public License Version 2. See the LICENSE file
  16. * at the top of the source tree.
  17. */
  18. /*!
  19. * \file
  20. * \author Russell Bryant <russell@digium.com>
  21. *
  22. * \brief A utility for reading from a raw TCP stream
  23. *
  24. * This application is intended for use when a raw TCP stream is desired to be
  25. * used as a music on hold source for Asterisk. Some devices are capable of
  26. * taking some kind of audio input and provide it as a raw TCP stream over the
  27. * network, which is what inspired someone to fund this to be written.
  28. * However, it would certainly be possible to write your own server application
  29. * to provide music over a TCP stream from a centralized location.
  30. *
  31. * This application is quite simple. It just reads the data from the TCP
  32. * stream and dumps it straight to stdout. Due to the way Asterisk handles
  33. * music on hold sources, this application checks to make sure writing
  34. * to stdout will not be a blocking operation before doing so. If so, the data
  35. * is just thrown away. This ensures that the stream will continue to be
  36. * serviced, even if Asterisk is not currently using the source.
  37. *
  38. * \todo Update this application to be able to connect to a stream via HTTP,
  39. * since that is the #1 most requested feature, and it would be quite useful.
  40. * A lot of people think that is what this is for and email me when it does
  41. * not work. :)
  42. */
  43. /*** MODULEINFO
  44. <support_level>extended</support_level>
  45. ***/
  46. #include <stdlib.h>
  47. #include <stdio.h>
  48. #include <string.h>
  49. #include <netdb.h>
  50. #include <unistd.h>
  51. #include <sys/types.h>
  52. #include <sys/socket.h>
  53. #if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__Darwin__) || defined(__CYGWIN__) || defined(__DragonFly__)
  54. #include <netinet/in.h>
  55. #endif
  56. #include <sys/time.h>
  57. int main(int argc, char *argv[])
  58. {
  59. struct sockaddr_in sin;
  60. struct hostent *hp;
  61. int s;
  62. int res;
  63. char buf[2048];
  64. fd_set wfds;
  65. struct timeval tv;
  66. if (argc != 3) {
  67. fprintf(stderr, "streamplayer -- A utility for reading from a raw TCP stream.\n");
  68. fprintf(stderr, "Written for use with Asterisk (http://www.asterisk.org)\n");
  69. fprintf(stderr, "Copyright (C) 2005 -- Russell Bryant -- Digium, Inc.\n\n");
  70. fprintf(stderr, "Usage: ./streamplayer <ip> <port>\n");
  71. exit(1);
  72. }
  73. hp = gethostbyname(argv[1]);
  74. if (!hp) {
  75. fprintf(stderr, "Unable to lookup IP for host '%s'\n", argv[1]);
  76. exit(1);
  77. }
  78. memset(&sin, 0, sizeof(sin));
  79. sin.sin_family = AF_INET;
  80. sin.sin_port = htons(atoi(argv[2]));
  81. memcpy(&sin.sin_addr, hp->h_addr, sizeof(sin.sin_addr));
  82. s = socket(AF_INET, SOCK_STREAM, 0);
  83. if (s < 0) {
  84. fprintf(stderr, "Unable to allocate socket!\n");
  85. exit(1);
  86. }
  87. res = connect(s, (struct sockaddr *)&sin, sizeof(sin));
  88. if (res) {
  89. fprintf(stderr, "Unable to connect to host!\n");
  90. close(s);
  91. exit(1);
  92. }
  93. while (1) {
  94. res = read(s, buf, sizeof(buf));
  95. if (res < 1)
  96. break;
  97. memset(&tv, 0, sizeof(tv));
  98. FD_ZERO(&wfds);
  99. FD_SET(1, &wfds);
  100. select(2, NULL, &wfds, NULL, &tv);
  101. if (FD_ISSET(1, &wfds)) {
  102. if (write(1, buf, res) < 1) {
  103. break;
  104. }
  105. }
  106. }
  107. close(s);
  108. exit(res);
  109. }