📄 tpjackd.c
字号:
/*----------------------------------------------------------------------*\ tpjackd.c Version: 1.0 3/99 1.1 4/99 1.2 4/27/99 - select() support enabled 1.3 4/28/99 - echo cancellation added, daemon enabled added fork() 1.4 5/25/99 - eliminated dns name req in backchannel audio udp connect, new module support 1.5 6/10/99 - changed license to LGPL This module is the daemon that tpjack connects to. Copyright (c) 1999 Quicknet Technologies, Inc. Written by Ed Okerson <eokerson@texasconnect.net> and Greg Herlein <gherlein@quicknet.net> * This is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License (LGPL) as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. It is also available online at * http://www.gnu.org/copyleft/lesser.html ----------------------------------------------------------------------*//*-------------------------------< RCS >--------------------------------*/static char RCS_ID[] = "$Id: tpjackd.c,v 1.1.1.1 1999/07/16 01:26:02 bogawa Exp $";/*----------------------------< Defines >-------------------------------*//*----------------------------< Includes >------------------------------*//* stdlib */#include <sys/types.h>#include <sys/signal.h>#include <sys/socket.h>#include <sys/time.h>#include <sys/resource.h>#include <sys/wait.h>#include <sys/errno.h>#include <sys/ioctl.h>#include <netinet/in.h>#include <stdio.h>#include <netdb.h>#include <varargs.h>//#include <stdarg.h>#include <fcntl.h>#include <errno.h>#include <syslog.h>/* other */#include "ixjuser.h"#include "udp.h"/*---------------------------< Definitions >----------------------------*/#define QLEN 5#define BUFSIZE 4096/*--------------------------< Declarations >----------------------------*/static int UDPjack(int fd);static int passiveTCP(char *service, int qlen);static int passivesock(char *service, char *protocol, int qlen);static void zombie_kill(int n);/*------------------------< Global Variables >--------------------------*/extern char szClientName[50];extern char szClientAddr[50];/*-------------------------< Local Variables >--------------------------*/static char szDevice[32];static u_short portbase = 0;static int nPort = 7000;/*----------------------------------------------------------------------*/intmain(int argc,char *argv[]){ struct sockaddr_in fsin; int alen, msock, ssock; switch(argc) { case 2: strncpy(szDevice,argv[1],sizeof(szDevice)); break; case 3: strncpy(szDevice,argv[1],sizeof(szDevice)); nPort=atoi(argv[2]); break; default: fprintf(stderr,"usage: tpjackd dev [port]\n"); fprintf(stderr," - dev is probably /dev/ixj0\n"); exit(1); } msock=passiveTCP(argv[2],QLEN); /* make this program a daemon */ daemon_init(); signal(SIGCHLD,zombie_kill); while (1) { alen=sizeof(fsin); ssock=accept(msock,(struct sockaddr *)&fsin, &alen); if (ssock < 0) { if (errno == EINTR) continue; errexit("accept: %s\n",sys_errlist[errno]); } switch(fork()) { case 0: close(msock); exit(UDPjack(ssock)); default: close(ssock); break; case -1: errexit("fork: %s\n",sys_errlist[errno]); } }}/*----------------------------------------------------------------------*/static intUDPjack(int fd){ char inbuf[BUFSIZE], outbuf[BUFSIZE]; int cc, ixj,read_fd,send_fd,n,hook,m_hook,retval,nMax; fd_set rfds; struct timeval tv; /* the fd passed in is the socket descriptor for the signalling socket first, we use it to identify the client */ n=IdentifyPeer(fd); if(n<0) errexit("failure on signalling socket\n"); log("connection from %s\n",szClientName); printf("connection from %s\n",szClientName); fflush(stdout); ixj = open(szDevice,O_RDWR); if(ixj<0) errexit("failure opening %s\n",szDevice); if(ioctl(ixj, IXJCTL_RING)) { /* connect the data ports */ read_fd=GetRecvSocket(nPort); send_fd=GetSendSocket(szClientAddr,nPort); if((read_fd<0)||(send_fd<0)) errexit("failure on udp socket\n"); ioctl(ixj,IXJCTL_PLAY_CODEC,TS85); ioctl(ixj,IXJCTL_REC_CODEC,TS85); ioctl(ixj,IXJCTL_REC_START); ioctl(ixj,IXJCTL_PLAY_START); ioctl(ixj,IXJCTL_AEC_START); while(hook=ioctl(ixj,IXJCTL_HOOKSTATE)) { FD_ZERO(&rfds); FD_SET(read_fd, &rfds); FD_SET(ixj, &rfds); tv.tv_sec = 0; tv.tv_usec = 300; retval = select(nMax,&rfds,NULL, NULL,&tv); if(FD_ISSET(ixj,&rfds)) { cc = read(ixj, outbuf, 32); if(cc > 0) { write(send_fd,outbuf,cc); } } if(FD_ISSET(read_fd,&rfds)) { cc = ReadUDP(read_fd,inbuf,sizeof inbuf); if(cc > 0) { write(ixj, inbuf, cc); } if(cc < 0) { if(errno!=EAGAIN) { ioctl(ixj, IXJCTL_REC_STOP); ioctl(ixj, IXJCTL_PLAY_STOP); ioctl(ixj, IXJCTL_AEC_STOP); errexit("echo read: %s\n",sys_errlist[errno]); } } } /* end if(retval) */ } /* end while() */ } close(read_fd); close(send_fd); close(fd); close(ixj); return 0;}/*----------------------------------------------------------------------*/static intpassiveTCP(char *service, int qlen){ return passivesock(service,"tcp",qlen);}/*----------------------------------------------------------------------*/static intpassivesock(char *service, char *protocol, int qlen){ struct servent *pse; struct protoent *ppe; struct sockaddr_in sin; int s, type; bzero((char *)&sin, sizeof(sin)); sin.sin_family = AF_INET; sin.sin_addr.s_addr = INADDR_ANY; if (pse = getservbyname(service,protocol)) sin.sin_port=htons(ntohs((u_short)pse->s_port)+portbase); else if ((sin.sin_port=htons((u_short)atoi(service)))==0) errexit("can't get \"%s\" service entry\n",service); if ((ppe = getprotobyname(protocol))==0) errexit("can't get \"%s\" protocol entry\n",protocol); if (strcmp(protocol, "udp")==0) type=SOCK_DGRAM; else type=SOCK_STREAM; s = socket(PF_INET,type,ppe->p_proto); if (s<0) errexit("can't create socket: %s\n",sys_errlist[errno]); if (bind(s,(struct sockaddr *)&sin, sizeof(sin))<0) errexit("can't bind to %s port: %s\n",service,sys_errlist[errno]); if (type==SOCK_STREAM && listen(s,qlen)<0) errexit("can't listen on %s port: %s\n",service,sys_errlist[errno]); return s;}/*----------------------------------------------------------------------*/intlog(format, va_alist)char *format;va_dcl{ va_list args; char szMsg[512]; va_start(args); vsprintf(szMsg,format,args); va_end(args); openlog("tpjack",LOG_CONS,LOG_DAEMON); syslog(LOG_ERR,szMsg); closelog(); return 0;}/*----------------------------------------------------------------------*/interrexit(format, va_alist)char *format;va_dcl{ va_list args; char szMsg[512]; va_start(args); vsprintf(szMsg,format,args); va_end(args); openlog("tpjack",LOG_CONS,LOG_DAEMON); syslog(LOG_ERR,szMsg); closelog(); exit(1);}/*----------------------------------------------------------------------*/static voidzombie_kill(int n){ union wait status; while (wait3(&status,WNOHANG,(struct rusage *)0) >= 0);}/*-------------------------------< End >--------------------------------*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -