tpjackd.c
上传用户:sy_wanhua
上传日期:2013-07-25
资源大小:3048k
文件大小:8k
源码类别:

流媒体/Mpeg4/MP4

开发平台:

C/C++

  1. /*----------------------------------------------------------------------*
  2.   tpjackd.c                                                 
  3.   
  4.   Version:     1.0   3/99
  5.                1.1   4/99 
  6.                1.2   4/27/99 - select() support enabled
  7.                1.3   4/28/99 - echo cancellation added, daemon enabled
  8.                                added fork()
  9.                1.4   5/25/99 - eliminated dns name req in backchannel
  10.                                audio udp connect, new module support
  11.                1.5   6/10/99 - changed license to LGPL
  12.                
  13.   This module is the daemon that tpjack connects to.
  14.   Copyright (c) 1999 Quicknet Technologies, Inc.
  15.     
  16.   Written by Ed Okerson <eokerson@texasconnect.net> and
  17.   Greg Herlein <gherlein@quicknet.net> 
  18.   
  19.  * This is free software; you can redistribute it and/or
  20.  * modify it under the terms of the GNU Lesser General Public
  21.  * License (LGPL) as published by the Free Software Foundation; either
  22.  * version 2 of the License, or (at your option) any later version.
  23.  *
  24.  * This software is distributed in the hope that it will be useful,
  25.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  26.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  27.  * General Public License for more details.
  28.  *
  29.  * You should have received a copy of the GNU Lesser General Public
  30.  * License along with this library; if not, write to the
  31.  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  32.  * Boston, MA 02111-1307, USA.  It is also available online at 
  33.  * http://www.gnu.org/copyleft/lesser.html
  34.  
  35. ----------------------------------------------------------------------*/
  36. /*-------------------------------< RCS >--------------------------------*/
  37. static char RCS_ID[] = "$Id: tpjackd.c,v 1.1.1.1 1999/08/05 21:17:32 luan Exp $";
  38. /*----------------------------< Defines >-------------------------------*/
  39. /*----------------------------< Includes >------------------------------*/
  40. /* stdlib */
  41. #include <sys/types.h>
  42. #include <sys/signal.h>
  43. #include <sys/socket.h>
  44. #include <sys/time.h>
  45. #include <sys/resource.h>
  46. #include <sys/wait.h>
  47. #include <sys/errno.h>
  48. #include <sys/ioctl.h>
  49. #include <netinet/in.h>
  50. #include <stdio.h>
  51. #include <netdb.h>
  52. #include <varargs.h>
  53. //#include <stdarg.h>
  54. #include <fcntl.h>
  55. #include <errno.h>
  56. #include <syslog.h>
  57. /* other */
  58. #include "ixjuser.h"
  59. #include "udp.h"
  60. /*---------------------------< Definitions >----------------------------*/
  61. #define QLEN 5
  62. #define BUFSIZE 480
  63. /*--------------------------< Declarations >----------------------------*/
  64. static int         UDPjack(int fd);
  65. static int         passiveTCP(char *service, int qlen);
  66. static int         passivesock(char *service, char *protocol, int qlen);
  67. static void        zombie_kill(int n);
  68. /*------------------------< Global Variables >--------------------------*/
  69. extern char        szClientName[50];
  70. extern char        szClientAddr[50];
  71. /*-------------------------< Local Variables >--------------------------*/
  72. static char        szDevice[32];
  73. static u_short     portbase = 0;
  74. static int         nPort = 7000;
  75. /*----------------------------------------------------------------------*/
  76. int
  77. main(int argc,char *argv[])
  78. {
  79.   struct sockaddr_in fsin;
  80.   int alen, msock, ssock;
  81.   
  82.   switch(argc)
  83.   {
  84.     case 2:
  85.       strncpy(szDevice,argv[1],sizeof(szDevice));
  86.       break;
  87.     case 3:
  88.       strncpy(szDevice,argv[1],sizeof(szDevice));
  89.       nPort=atoi(argv[2]);
  90.       break;
  91.     default:
  92.       fprintf(stderr,"usage: tpjackd dev [port]n");
  93.       fprintf(stderr," - dev is probably /dev/ixj0n");
  94. exit(1);
  95.   }
  96.   msock=passiveTCP(argv[2],QLEN);
  97.   
  98.   /* make this program a daemon */
  99.   daemon_init();
  100.   signal(SIGCHLD,zombie_kill);
  101.     
  102.   while (1)
  103.   {
  104.     alen=sizeof(fsin);
  105.     ssock=accept(msock,(struct sockaddr *)&fsin, &alen);
  106.     if (ssock < 0)
  107.     {
  108.       if (errno == EINTR) continue;
  109.       errexit("accept: %sn",sys_errlist[errno]);
  110.     }
  111.     switch(fork())
  112.     {
  113.       case 0:
  114.         close(msock);
  115.         exit(UDPjack(ssock));
  116.       default:
  117.         close(ssock);
  118.         break;
  119.       case -1:
  120.         errexit("fork: %sn",sys_errlist[errno]);
  121.     }
  122.   }
  123. }
  124. /*----------------------------------------------------------------------*/
  125. static int
  126. UDPjack(int fd)
  127. {
  128.   char inbuf[BUFSIZE], outbuf[BUFSIZE];
  129.   int  cc, ixj,read_fd,send_fd,n,hook,m_hook,retval,nMax;
  130.   fd_set          rfds;
  131.   struct timeval  tv;
  132.   /* the fd passed in is the socket descriptor for the signalling socket
  133.      first, we use it to identify the client 
  134.   */
  135.   n=IdentifyPeer(fd);
  136.   if(n<0) errexit("failure on signalling socketn");
  137.   log("connection from %sn",szClientName);
  138.   printf("connection from %sn",szClientName);
  139.   fflush(stdout);
  140.   
  141.   ixj = open(szDevice,O_RDWR);
  142.   if(ixj<0) errexit("failure opening %sn",szDevice);
  143.   if(ioctl(ixj, IXJCTL_RING))
  144.   {
  145.     /* connect the data ports */
  146.     read_fd=GetRecvSocket(nPort);
  147.     send_fd=GetSendSocket(szClientAddr,nPort);
  148.     if((read_fd<0)||(send_fd<0)) errexit("failure on udp socketn");
  149.     ioctl(ixj,IXJCTL_PLAY_CODEC,LINEAR16);
  150.     ioctl(ixj,IXJCTL_REC_CODEC,LINEAR16);
  151.     ioctl(ixj,IXJCTL_REC_START);
  152.     ioctl(ixj,IXJCTL_PLAY_START);
  153.     ioctl(ixj,IXJCTL_AEC_START);
  154.     while(hook=ioctl(ixj,IXJCTL_HOOKSTATE))
  155.     {
  156.       FD_ZERO(&rfds);
  157.       FD_SET(read_fd, &rfds);
  158.       FD_SET(ixj, &rfds);
  159.       tv.tv_sec = 0;
  160.       tv.tv_usec = 300;
  161.       retval = select(nMax,&rfds,NULL, NULL,&tv);
  162.       if(FD_ISSET(ixj,&rfds))
  163.       {
  164.         cc = read(ixj, outbuf, 480);
  165.         if(cc > 0)
  166.         {
  167.           write(send_fd,outbuf,cc);
  168.         }
  169.       }
  170.       if(FD_ISSET(read_fd,&rfds))
  171.       {
  172.         cc = ReadUDP(read_fd,inbuf,sizeof inbuf);
  173.         if(cc > 0)
  174.         {
  175.           write(ixj, inbuf, cc);
  176.         }
  177.         if(cc < 0)
  178.         {
  179.           if(errno!=EAGAIN)
  180.           {
  181.             ioctl(ixj, IXJCTL_AEC_STOP);
  182.             ioctl(ixj, IXJCTL_REC_STOP);
  183.             ioctl(ixj, IXJCTL_PLAY_STOP);
  184.             errexit("echo read: %sn",sys_errlist[errno]);
  185.           }
  186.         }
  187.       } /* end if(retval) */
  188.     } /* end while() */
  189.   }
  190.   close(read_fd);
  191.   close(send_fd);
  192.   close(fd);
  193.   close(ixj);
  194.   return 0;
  195. }
  196. /*----------------------------------------------------------------------*/
  197. static int
  198. passiveTCP(char *service, int qlen)
  199. {
  200.   return passivesock(service,"tcp",qlen);
  201. }
  202. /*----------------------------------------------------------------------*/
  203. static int
  204. passivesock(char *service, char *protocol, int qlen)
  205. {
  206.   struct servent *pse;
  207.   struct protoent *ppe;
  208.   struct sockaddr_in sin;
  209.   int s, type;
  210.   bzero((char *)&sin, sizeof(sin));
  211.   sin.sin_family = AF_INET;
  212.   sin.sin_addr.s_addr = INADDR_ANY;
  213.   if (pse = getservbyname(service,protocol))
  214.     sin.sin_port=htons(ntohs((u_short)pse->s_port)+portbase);
  215.   else if ((sin.sin_port=htons((u_short)atoi(service)))==0)
  216.     errexit("can't get "%s" service entryn",service);
  217.   if ((ppe = getprotobyname(protocol))==0)
  218.     errexit("can't get "%s" protocol entryn",protocol);
  219.   if (strcmp(protocol, "udp")==0)
  220.     type=SOCK_DGRAM;
  221.   else
  222.     type=SOCK_STREAM;
  223.   s = socket(PF_INET,type,ppe->p_proto);
  224.   if (s<0)
  225.     errexit("can't create socket: %sn",sys_errlist[errno]);
  226.   if (bind(s,(struct sockaddr *)&sin, sizeof(sin))<0)
  227.     errexit("can't bind to %s port: %sn",service,sys_errlist[errno]);
  228.   if (type==SOCK_STREAM && listen(s,qlen)<0)
  229.     errexit("can't listen on %s port: %sn",service,sys_errlist[errno]);
  230.   return s;
  231. }
  232. /*----------------------------------------------------------------------*/
  233. int
  234. log(format, va_alist)
  235. char *format;
  236. va_dcl
  237. {
  238.   va_list        args;
  239.   char           szMsg[512];
  240.   va_start(args);
  241.   vsprintf(szMsg,format,args);
  242.   va_end(args);
  243.   openlog("tpjack",LOG_CONS,LOG_DAEMON);
  244.   syslog(LOG_ERR,szMsg);
  245.   closelog();
  246.   return 0;
  247. }
  248. /*----------------------------------------------------------------------*/
  249. int
  250. errexit(format, va_alist)
  251. char *format;
  252. va_dcl
  253. {
  254.   va_list        args;
  255.   char           szMsg[512];
  256.   va_start(args);
  257.   vsprintf(szMsg,format,args);
  258.   va_end(args);
  259.   openlog("tpjack",LOG_CONS,LOG_DAEMON);
  260.   syslog(LOG_ERR,szMsg);
  261.   closelog();
  262.   exit(1);
  263. }
  264. /*----------------------------------------------------------------------*/
  265. static void
  266. zombie_kill(int n)
  267. {
  268.   union wait status;
  269.   while (wait3(&status,WNOHANG,(struct rusage *)0) >= 0);
  270. }
  271. /*-------------------------------< End >--------------------------------*/