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

流媒体/Mpeg4/MP4

开发平台:

C/C++

  1. /* ====================================================================
  2.  * The Vovida Software License, Version 1.0 
  3.  * 
  4.  * Copyright (c) 2000 Vovida Networks, Inc.  All rights reserved.
  5.  * 
  6.  * Redistribution and use in source and binary forms, with or without
  7.  * modification, are permitted provided that the following conditions
  8.  * are met:
  9.  * 
  10.  * 1. Redistributions of source code must retain the above copyright
  11.  *    notice, this list of conditions and the following disclaimer.
  12.  * 
  13.  * 2. Redistributions in binary form must reproduce the above copyright
  14.  *    notice, this list of conditions and the following disclaimer in
  15.  *    the documentation and/or other materials provided with the
  16.  *    distribution.
  17.  * 
  18.  * 3. The names "VOCAL", "Vovida Open Communication Application Library",
  19.  *    and "Vovida Open Communication Application Library (VOCAL)" must
  20.  *    not be used to endorse or promote products derived from this
  21.  *    software without prior written permission. For written
  22.  *    permission, please contact vocal@vovida.org.
  23.  *
  24.  * 4. Products derived from this software may not be called "VOCAL", nor
  25.  *    may "VOCAL" appear in their name, without prior written
  26.  *    permission of Vovida Networks, Inc.
  27.  * 
  28.  * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
  29.  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  30.  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
  31.  * NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL VOVIDA
  32.  * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES
  33.  * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
  34.  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  35.  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  36.  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
  37.  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  38.  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
  39.  * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
  40.  * DAMAGE.
  41.  * 
  42.  * ====================================================================
  43.  * 
  44.  * This software consists of voluntary contributions made by Vovida
  45.  * Networks, Inc. and many individuals on behalf of Vovida Networks,
  46.  * Inc.  For more information on Vovida Networks, Inc., please see
  47.  * <http://www.vovida.org/>.
  48.  *
  49.  */
  50. /*-------------------------------< RCS >--------------------------------*/
  51. static char RCS_ID[] = "$Id: tpjackd.cxx,v 1.5 2000/12/18 23:44:52 bko Exp $";
  52. /*----------------------------< Defines >-------------------------------*/
  53. /*----------------------------< Includes >------------------------------*/
  54. /* stdlib */
  55. #include <sys/types.h>
  56. #include <sys/signal.h>
  57. #include <sys/socket.h>
  58. #include <sys/time.h>
  59. #include <sys/resource.h>
  60. #include <sys/wait.h>
  61. #include <sys/errno.h>
  62. #include <sys/ioctl.h>
  63. #include <netinet/in.h>
  64. #include <arpa/inet.h>
  65. #include <stdio.h>
  66. #include <netdb.h>
  67. //#include <varargs.h>
  68. #include <stdarg.h>
  69. #include <fcntl.h>
  70. #include <errno.h>
  71. #include <syslog.h>
  72. #include <unistd.h>
  73. #include <sys/stat.h>
  74. #include <fstream>
  75. /* other */
  76. #include <iostream>
  77. #include "ixjuser.h"
  78. #include "RtpSession.hxx"
  79. /*---------------------------< Definitions >----------------------------*/
  80. #define QLEN 5
  81. #define BUFSIZE 256
  82. /*--------------------------< Declarations >----------------------------*/
  83. static int RTPjack(int fd);
  84. static int passiveTCP(char *service, int qlen);
  85. static int passivesock(char *service, char *protocol, int qlen);
  86. static void zombie_kill(int n);
  87. int IdentifyPeer(int nSock);
  88. int GetNameFromAddr(char* szIP, char* szName, int nLenName);
  89. /*------------------------< Global Variables >--------------------------*/
  90. char szClientName[50];
  91. char szClientAddr[50];
  92. /*-------------------------< Local Variables >--------------------------*/
  93. static char szDevice[32];
  94. static u_short portbase = 0;
  95. static int nPort = 7000;
  96. int
  97. daemon_init(void)
  98. {
  99.     pid_t pid;
  100.     pid = fork();
  101.     if (pid < 0) return -1;
  102.     else if (pid != 0) exit(0);  /* parent exits */
  103.     /* child continues and become session leader */
  104.     setsid();
  105.     return 0;
  106. }
  107. /*----------------------------------------------------------------------*/
  108. int
  109. main(int argc, char *argv[])
  110. {
  111.     struct sockaddr_in fsin;
  112.     int msock, ssock;
  113.     unsigned int alen;
  114.     switch (argc)
  115.     {
  116.         case 2:
  117.         // strncpy(szDevice,"/dev/ixj0",sizeof(szDevice));
  118.         strncpy(szDevice, "/dev/phone0", sizeof(szDevice));
  119.         nPort = atoi(argv[1]);
  120.         break;
  121.         //    case 3:
  122.         //      strncpy(szDevice,argv[1],sizeof(szDevice));
  123.         //      nPort=atoi(argv[2]);
  124.         //      break;
  125.         default:
  126.         //      fprintf(stderr,"usage: tpjackd dev [port]n");
  127.         //      fprintf(stderr," - dev is probably /dev/ixj0n");
  128.         fprintf(stderr, "usage: tpjackd portn");
  129.         exit(1);
  130.     }
  131.     msock = passiveTCP(argv[1], QLEN);
  132.     /* make this program a daemon */
  133.     daemon_init();
  134.     signal(SIGCHLD, zombie_kill);
  135.     while (1)
  136.     {
  137.         alen = sizeof(fsin);
  138.         ssock = accept(msock, (struct sockaddr *) & fsin, &alen);
  139.         if (ssock < 0)
  140.         {
  141.             if (errno == EINTR) continue;
  142.             printf("accept: %sn", sys_errlist[errno]);
  143.         }
  144.         switch (fork())
  145.         {
  146.             case 0:
  147.             close(msock);
  148.             exit(RTPjack(ssock));
  149.             default:
  150.             close(ssock);
  151.             break;
  152.             case - 1:
  153.             printf("fork: %sn", sys_errlist[errno]);
  154.         }
  155.     }
  156. }
  157. /*----------------------------------------------------------------------*/
  158. static int
  159. RTPjack(int fd)
  160. {
  161.     int cc, ixj, read_fd, send_fd, readc_fd, sendc_fd, n, hook, m_hook, retval, nMax;
  162.     fd_set rfds;
  163.     struct timeval tv;
  164.     /* the fd passed in is the socket descriptor for the signalling socket
  165.        first, we use it to identify the client 
  166.     */
  167.     n = IdentifyPeer(fd);
  168.     if (n < 0) printf("failure on signalling socketn");
  169.     printf("connection from %sn", szClientName);
  170.     fflush(stdout);
  171.     ixj = open(szDevice, O_RDWR);
  172.     if (ixj < 0) printf("failure opening %sn", szDevice);
  173.     if (ioctl(ixj, IXJCTL_RING))
  174.     {
  175.         /* connect the data ports */
  176.         RtpSession dataStack(szClientAddr, nPort + 1, nPort + 1, nPort + 2, nPort + 2);
  177.         RtpPacket* outPacket = dataStack.createPacket(BUFSIZE);
  178.         RtpPacket* inPacket = NULL;
  179.         read_fd = (dataStack.getRtpRecv())->getSocketFD();
  180.         send_fd = (dataStack.getRtpTran())->getSocketFD();
  181.         readc_fd = (dataStack.getRtcpRecv())->getSocketFD();
  182.         sendc_fd = (dataStack.getRtcpTran())->getSocketFD();
  183.         if ((read_fd < 0) || (send_fd < 0) || (readc_fd < 0) || (sendc_fd < 0))
  184.             printf("failure on RTP socketn");
  185.         ioctl(ixj, IXJCTL_PLAY_CODEC, ULAW);
  186.         ioctl(ixj, IXJCTL_REC_CODEC, ULAW);
  187.         ioctl(ixj, IXJCTL_REC_START);
  188.         ioctl(ixj, IXJCTL_PLAY_START);
  189.         ioctl(ixj, IXJCTL_AEC_START);
  190.         while (hook = ioctl(ixj, IXJCTL_HOOKSTATE))
  191.         {
  192.             FD_ZERO(&rfds);
  193.             FD_SET(read_fd, &rfds);
  194.             FD_SET(readc_fd, &rfds);
  195.             FD_SET(ixj, &rfds);
  196.             tv.tv_sec = 0;
  197.             tv.tv_usec = 300;
  198.             retval = select(nMax, &rfds, NULL, NULL, &tv);
  199.             if (FD_ISSET(ixj, &rfds))                    // read data from phone
  200.             {
  201.                 cc = read(ixj, outPacket->getPayloadLoc(), 240);
  202.                 outPacket->setRtpTime(dataStack.getPrevRtpTime() + 240);
  203.                 if (cc > 0)
  204.                 {
  205.                     assert (cc == 240);
  206.                     outPacket->setPayloadUsage(cc);
  207.                     outPacket->setRtpTime(dataStack.getPrevRtpTime() + 240);
  208.                     dataStack.transmit(outPacket);
  209.                 }
  210.             }
  211.             if (1 || FD_ISSET(read_fd, &rfds))                // read data from network
  212.             {
  213.                 inPacket = dataStack.receive();
  214.                 if (inPacket)
  215.                 {
  216.                     assert (inPacket->getPayloadUsage() == 240);
  217.                     write(ixj, inPacket->getPayloadLoc(), inPacket->getPayloadUsage());
  218.                 }
  219.                 else
  220.                 {
  221.                     /* if(errno!=EAGAIN)
  222.                        {
  223.                          ioctl(ixj, IXJCTL_REC_STOP);
  224.                          ioctl(ixj, IXJCTL_PLAY_STOP);
  225.                          ioctl(ixj, IXJCTL_AEC_STOP);
  226.                          printf("echo read: %sn",sys_errlist[errno]);
  227.                        } */
  228.                 }
  229.             }
  230.             dataStack.processRTCP();
  231.         } /* end while() */
  232.     }
  233.     close(read_fd);
  234.     close(send_fd);
  235.     close(readc_fd);
  236.     close(sendc_fd);
  237.     close(fd);
  238.     close(ixj);
  239.     return 0;
  240. }
  241. /*----------------------------------------------------------------------*/
  242. static int
  243. passiveTCP(char *service, int qlen)
  244. {
  245.     return passivesock(service, "tcp", qlen);
  246. }
  247. /*----------------------------------------------------------------------*/
  248. static int
  249. passivesock(char *service, char *protocol, int qlen)
  250. {
  251.     struct servent *pse;
  252.     struct protoent *ppe;
  253.     struct sockaddr_in sin;
  254.     int s, type;
  255.     bzero((char *)&sin, sizeof(sin));
  256.     sin.sin_family = AF_INET;
  257.     sin.sin_addr.s_addr = INADDR_ANY;
  258.     if (pse = getservbyname(service, protocol))
  259.         sin.sin_port = htons(ntohs((u_short)pse->s_port) + portbase);
  260.     else if ((sin.sin_port = htons((u_short)atoi(service))) == 0)
  261.         printf("can't get "%s" service entryn", service);
  262.     if ((ppe = getprotobyname(protocol)) == 0)
  263.         printf("can't get "%s" protocol entryn", protocol);
  264.     if (strcmp(protocol, "udp") == 0)
  265.         type = SOCK_DGRAM;
  266.     else
  267.         type = SOCK_STREAM;
  268.     s = socket(PF_INET, type, ppe->p_proto);
  269.     if (s < 0)
  270.         printf("can't create socket: %sn", sys_errlist[errno]);
  271.     if (bind(s, (struct sockaddr *)&sin, sizeof(sin)) < 0)
  272.         printf("can't bind to %s port: %sn", service, sys_errlist[errno]);
  273.     if (type == SOCK_STREAM && listen(s, qlen) < 0)
  274.         printf("can't listen on %s port: %sn", service, sys_errlist[errno]);
  275.     return s;
  276. }
  277. /*----------------------------------------------------------------------*/
  278. int
  279. IdentifyPeer(int nSock)
  280. {
  281.     struct sockaddr_in sPeer;
  282.     int n;
  283.     unsigned int nSize;
  284.     char* p;
  285.     /* get the name and address of the client */
  286.     nSize = sizeof(sPeer);
  287.     n = getpeername(nSock, (struct sockaddr*) & sPeer, &nSize);
  288.     if (n == -1)
  289.     {
  290.         printf("Unable to get peer name infon");
  291.         return -1;
  292.     }
  293.     p = inet_ntoa(sPeer.sin_addr);
  294.     strncpy(szClientAddr, p, sizeof(szClientAddr));
  295.     GetNameFromAddr(szClientAddr, szClientName, sizeof(szClientName));
  296.     return 1;
  297. }
  298. /*----------------------------------------------------------------------*/
  299. int
  300. GetNameFromAddr(char* szIP, char* szName, int nLenName)
  301. {
  302.     struct sockaddr_in sPeer;
  303.     int n;
  304.     struct hostent* pHe;
  305.     /* get the name and address of the IP address passed in */
  306.     n = inet_aton(szIP, &sPeer.sin_addr);
  307.     if ((pHe = gethostbyaddr((char*) & sPeer.sin_addr, sizeof(sPeer.sin_addr),
  308.                              AF_INET)) == NULL)
  309.     {
  310.         printf("Unable to get peer address infon");
  311.         return -1;
  312.     }
  313.     memset(szName, 0x00, nLenName);
  314.     strncpy(szName, pHe->h_name, nLenName - 1);
  315.     return 1;
  316. }
  317. /*----------------------------------------------------------------------*/
  318. static void
  319. zombie_kill(int n)
  320. {
  321.     union wait status;
  322.     while (wait3(&status, WNOHANG, (struct rusage *)0) >= 0);
  323. }
  324. /*-------------------------------< End >--------------------------------*/