⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 smodlib.c

📁 使用USR和RockWell Modem的语音Modem程序
💻 C
📖 第 1 页 / 共 2 页
字号:
//************************************************************//  smodlib.cpp - source file for voice manipulation library for//          USR Sportster voice modem with speakerphone.//************************************************************#include "incall.h"// Timer flagModemStatus MState;GlobInit glb;void GlobInit::PrepareAll(){      struct sigaction act, oact;      openlog( "gspk", LOG_CONS, LOG_DAEMON);    // Enable signal handling for the child.    act.sa_handler =  timeout;   sigemptyset( &act.sa_mask );   act.sa_flags = 0;   #ifdef SA_RESTART   act.sa_flags |= SA_RESTART;   #endif   if (sigaction( SIGALRM, &act, &oact) < 0)    {      syslog(LOG_CRIT,"Cannot catch SIGALRM");      return;   }};void GlobInit::CloseAll(){   closelog();}int iTimedOut = 0;void timeout(int){   iTimedOut = 1;};//***************************************************************//***************************************************************////  class PortParam////***************************************************************//***************************************************************PortParam::PortParam(char* PName){   IsSetup = 0;   PortName = NULL;   if (PName == NULL) return;   PortName = new char[strlen(PName) + 1];   strcpy(PortName, PName);};int PortParam::SetPortMode(int speed){   struct termios tdes;   int fd;   if (PortName == NULL)   {      syslog(LOG_CRIT,"Port name is not defined in PortParam::SetPortMode!");      return 0;   }   // Open port    fd = open( PortName, O_RDWR | O_NONBLOCK);   if (fd == -1)    {      syslog(LOG_CRIT,"Unable to open modem port:");      syslog(LOG_CRIT,PortName);      return 0;   }   if (!isatty(fd))    {      syslog(LOG_CRIT,"Specified device is not a terminal:");      syslog(LOG_CRIT,PortName);      close(fd);      return 0;   }   if (tcgetattr ( fd, &told ) < 0)    {      syslog(LOG_CRIT,"tcgetattr failure");      close(fd);      return 0;   }   if (tcgetattr ( fd, &tdes ) < 0)    {      syslog(LOG_CRIT,"tcgetattr failure");      close(fd);      return 0;   }      tdes.c_iflag = IGNBRK  | IGNPAR;    // BRKINT  | PARMRK | INPCK | ISTRIP | INLCR | IGNCR | ICRNL |    // IUCLC | IXON | IXANY | IXOFF | IMAXBEL    tdes.c_oflag =  0;   // OPOST | OLCUC | ONLCR | OCRNL | ONOCR | ONLRET | OFILL |    // OFDEL | NLDLY | NL0 | NL1 | CRDLY | CR0 | CR1 | CR2 | CR3 |    // TABDLY | TAB0 | TAB1 | TAB2 | TAB3 | XTABS | BSDLY | BS0 |    // BS1 | VTDLY | VT0 | VT1 | FFDLY | FF0 | FF1   tdes.c_cflag = CS8 | HUPCL | CLOCAL | CRTSCTS | CREAD;   // CBAUD | EXTA | EXTB | CSIZE | CS5 | CS6 | CS7 | CSTOPB |    // CREAD | PARENB | PARODD | CIBAUD |    switch (speed)    {      case 0: tdes.c_cflag |= B0; break;      case 50: tdes.c_cflag |= B50; break;      case 75: tdes.c_cflag |= B75; break;      case 110: tdes.c_cflag |= B110; break;      case 134: tdes.c_cflag |= B134; break;      case 150: tdes.c_cflag |= B150; break;      case 200: tdes.c_cflag |= B200; break;      case 300: tdes.c_cflag |= B300; break;      case 600: tdes.c_cflag |= B600; break;      case 1200: tdes.c_cflag |= B1200; break;      case 1800: tdes.c_cflag |= B1800; break;      case 2400: tdes.c_cflag |= B2400; break;      case 4800: tdes.c_cflag |= B4800; break;      case 9600: tdes.c_cflag |= B9600; break;      case 19200: tdes.c_cflag |= B19200; break;      case 38400: tdes.c_cflag |= B38400; break;#ifdef B57600      case 57600: tdes.c_cflag |= B57600; break;#endif#ifdef B115200      case 115200: tdes.c_cflag |= B115200; break;#endif#ifdef B230400      case 230400: tdes.c_cflag |= B230400; break;#endif#ifdef B460800      case 460800: tdes.c_cflag |= B460800; break;#endif      default: tdes.c_cflag |= B38400; break;   };   tdes.c_lflag = 0;   // ISIG | ICANON | XCASE | ECHO | ECHOE | ECHOK | ECHONL |    // NOFLSH | TOSTOP | ECHOCTL | ECHOPRT | ECHOKE | FLUSHO |    // PENDIN | IEXTEN    if (tcsetattr ( fd, TCSANOW, &tdes ) < 0)    {      syslog(LOG_CRIT,"tcsetattr failure: Unable to set port settings!");      close(fd);      return 0;   }   close(fd);   IsSetup = 1;   return 1;}; int PortParam::RestorePortMode(){   int fd;   if (!IsSetup) return 1;   if (PortName == NULL)   {      syslog(LOG_WARNING,"Port name is not defined in PortParam::RestorePortMode!");      return 0;   }   // Open port    fd = open( PortName, O_RDWR | O_NONBLOCK);   if (fd == -1)    {      syslog(LOG_WARNING,"Unable to open modem port:");      syslog(LOG_WARNING,PortName);      return 0;   }   if (!isatty(fd))    {      syslog(LOG_WARNING,"Specified device is not a terminal:");      syslog(LOG_WARNING,PortName);      close(fd);      return 0;   }   if (tcsetattr ( fd, TCSANOW, &told ) < 0)    {      syslog(LOG_CRIT,"tcsetattr failure: Unable to set port settings!");      close(fd);      return 0;   }   close(fd);   IsSetup = 0;   return 1;};//***************************************************************//***************************************************************////  global functions////***************************************************************//***************************************************************char* memstr( char* where, char* what, int howmuch){   char* ptrf;   int i,j;   if (strlen(what) >= 1)    {      for (i = 0; i < howmuch; i++)       {         if (what[0] == where[i])          {            // compare further...            j = i + 1;            ptrf = &(what[1]);            while (*ptrf != '\0' && *ptrf == where[j] &&                j < howmuch ) ptrf++,j++;            if (*ptrf == '\0') return &(where[i]);          }      }      return NULL;   }   return where;}//***************************************************************//***************************************************************////  class VModem////***************************************************************//***************************************************************VModem::VModem(ConfigInfo* con) {   if (con == NULL)   {      syslog(LOG_ERR, "Empty parameter passed into VModem!");      exit(-1);   }   conf = con;   inData = 0;   inDTMF = 0;   inPubDTMF = 0;   MsgExchTimeOut = 3; // Three seconds time out for now...   StopChild = 0;   ttyParm = new PortParam(conf->SerialPort);};int VModem::Init(ConfigInfo* con) {   if (con == NULL)   {      syslog(LOG_ERR, "Empty parameter passed into VModem!");      return 0;   }   conf = con;   inData = 0;   inDTMF = 0;   inPubDTMF = 0;   MsgExchTimeOut = 3; // Three seconds time out for now...   StopChild = 0;   ttyParm = new PortParam(conf->SerialPort);   return 1;};VModem::~VModem(){   if (isParent)   {      StopRead(); // kill the child process      ttyParm->RestorePortMode();   }   delete ttyParm;};//static VModem* TThis;//static void dispatchsig(int)//{//   if (TThis) TThis->GotSignal();//};////static void finishchild(int)//{//   if (TThis) TThis->GotSignal2();//};int VModem::InitRead(){//   char buf[5]; // Buffer for the characters read from the port.              // For now, read one at a time.//   struct sigaction act, oact;   // Set the port to more appropriate mode -- RAW!!!!   if (ttyParm->SetPortMode(conf->PortSpeed) == 0)    {      return 0;   }   // Open port for reading...   fd = open(conf->SerialPort, O_RDWR/* | O_NONBLOCK*/);   if (fd == -1)    {      syslog(LOG_CRIT,"Unable to open modem port for reading");      return 0;   }   {      struct termios tdes;      if (tcgetattr ( fd, &tdes ) < 0)       {         syslog(LOG_CRIT,"tcgetattr failure");         close(fd);         return 0;      }            tdes.c_iflag = IGNBRK  | IGNPAR;       tdes.c_oflag =  0;      tdes.c_cflag = CS8 | HUPCL | CLOCAL | CRTSCTS | CREAD;      switch (conf->PortSpeed)       {         case 0: tdes.c_cflag |= B0; break;         case 50: tdes.c_cflag |= B50; break;         case 75: tdes.c_cflag |= B75; break;         case 110: tdes.c_cflag |= B110; break;         case 134: tdes.c_cflag |= B134; break;         case 150: tdes.c_cflag |= B150; break;         case 200: tdes.c_cflag |= B200; break;         case 300: tdes.c_cflag |= B300; break;         case 600: tdes.c_cflag |= B600; break;         case 1200: tdes.c_cflag |= B1200; break;         case 1800: tdes.c_cflag |= B1800; break;         case 2400: tdes.c_cflag |= B2400; break;         case 4800: tdes.c_cflag |= B4800; break;         case 9600: tdes.c_cflag |= B9600; break;         case 19200: tdes.c_cflag |= B19200; break;         case 38400: tdes.c_cflag |= B38400; break;#ifdef B57600         case 57600: tdes.c_cflag |= B57600; break;#endif#ifdef B115200         case 115200: tdes.c_cflag |= B115200; break;#endif#ifdef B230400         case 230400: tdes.c_cflag |= B230400; break;#endif#ifdef B460800         case 460800: tdes.c_cflag |= B460800; break;#endif         default: tdes.c_cflag |= B38400; break;      };      tdes.c_lflag = 0;      if (tcsetattr ( fd, TCSANOW, &tdes ) < 0)       {         syslog(LOG_CRIT,"tcsetattr failure: Unable to set port settings!");         close(fd);         return 0;      }   }   return 1;   // Create a pipe from the child to the parent -- this way we transfer info   // received from the modem. Sorry for these complications, I just   // want to empty the modem buffer as soon as possible.//   if (pipe(pipeD) < 0) //   {//      syslog(LOG_CRIT,"Cannot create a pipe -- Geeeez I hope this is not DOS!");//      return 0;//   }////   TThis = this;////   // Create a thread that will always read the port.//   ChildID = fork();//   if (ChildID == -1) //   {//      syslog(LOG_CRIT,"Can't fork -- sorry!");//      return 0;//   }////   // If this is a parent//   if (ChildID != 0)//   {////      // Enable signal handling for the parent. //      act.sa_handler =  dispatchsig;//      sigemptyset( &act.sa_mask );//      act.sa_flags = 0;////      #ifdef SA_RESTART//      act.sa_flags |= SA_RESTART;//      #endif////      if (sigaction( SIGUSR1, &act, &oact) < 0) //      {//         syslog(LOG_CRIT,"Cannot catch SIGUSR1");//         return 0;//      }////      close(pipeD[1]);////      isParent = 1;//      return 1;//   }////   // Child closes receiving end ...//   close(pipeD[0]);//   isParent = 0;////   // Enable signal handling for the child. //   act.sa_handler =  finishchild;//   sigemptyset( &act.sa_mask );//   act.sa_flags = 0;////   #ifdef SA_INTERRUPT//   act.sa_flags |= SA_INTERRUPT;//   #endif////   if (sigaction( SIGINT, &act, &oact) < 0) //   {//      syslog(LOG_CRIT,"Cannot catch SIGINT");//      return 0;//   }////   ParentID = getppid();////   do //   {//      if (read(fd, buf, 1) == 1) //      {//         write(pipeD[1], buf, 1);//         kill(ParentID, SIGUSR1);////         buf[1] = '\0';//         //syslog(LOG_DEBUG, "Pushed into pipe:");//         //syslog(LOG_DEBUG, buf );//      }//   } while (StopChild == 0);////   close(fd);//   syslog(LOG_DEBUG,"Child terminates.");//   exit(0);};void VModem::ReadFromPort(){   char buf[256];   int numread;   int retval;   fd_set rset;   struct timeval tmdly;   tmdly.tv_sec = 0;   tmdly.tv_usec = 0;   FD_ZERO(&rset);   FD_SET(GetPortFD(), &rset);   retval = select(1+GetPortFD(), &rset, NULL, NULL, &tmdly);   if ( retval < 1 ) return;   numread = read( GetPortFD(), buf, sizeof(buf)-1);   if (numread > 0)    {      buf[numread] = '\0';      //syslog(LOG_DEBUG, "Got:");      //syslog(LOG_DEBUG, buf );//if (buf[0] == DLE)//putchar('*');            // Check for DTMF signals.      // They always start with DLE      if (LastRec == DLE)      {         memmove(&(buf[1]), buf, numread);         numread++;         buf[0] = DLE;      }      LastRec = DLE;      for ( int i = 0; i < numread-1; i++ )      {         if (buf[i] == DLE)         {            // DLE was detected! Decode it.            if ( buf[i+1] == DLE ) // Received double DLE, just make it one            {               if ( i+2 == numread ) LastRec = 0; // Last DLE not to be counted               memmove(&buf[i],&buf[i+1],numread - i - 1);               numread--;            } else  // DTMF command, decode it.            {               DTMF[inDTMF] = buf[i+1];               inDTMF++;               if ( numread - i - 2 > 0 ) // Remove DTMF from the data stream               {                  memmove(&buf[i],&buf[i+2],numread - i - 2);                  i--;               }               numread = numread - 2;            }         }      }      if ( numread == 0)       {         LastRec = 0;         return;      }      if ( buf[numread-1] != DLE ) LastRec = 0;      if (LastRec == DLE) return;         // We need to add received data to the buffer...      // Check for overflow situation      if ((unsigned int)(inData + numread + 2) > sizeof(Data))       {         syslog(LOG_WARNING,"Incoming buffer overflow, ... truncating");         char* to = Data;         char* from = Data + sizeof(Data)/2;         for (unsigned int i = 0; i < sizeof(Data); i++)         {            *to++ = *from++;         }         inData -= sizeof(Data)/2;        }         for (int i = 0; i < numread; i++)       {         Data[inData++] = buf[i];      }   }};// Execute sequence of commands. If some commands// times out, will repeat it up to three timesint VModem::ExecuteSequence( CommandSequence* CommandSeq ){   int retval;   CommandSequence* cmd = CommandSeq;   while( cmd )   {      retval = 0;      for (int i = 0; i < 3; i++)      {         if (MsgExchange(cmd->GetCommand(), cmd->GetAnswer()) >= 0)         {            retval = 1;            break;         }      }      if (!retval) return 0;      cmd = cmd->GetNext();   }   return 1;}int VModem::MsgExchange( char* MsgSnd, char* MsgExpect ){   PREP_ALARM;   char newline[3] = {'\015','\012','\0'};   int ExchComplete = 0;   char allbuf[256];   strcpy(allbuf, MsgSnd);   strcat(allbuf, newline);//   sigset_t usrmask, oldmask;   FlushRecBuffer();   CHECK_ABORT_0;   syslog(LOG_DEBUG,"Sending:");   syslog(LOG_DEBUG,MsgSnd);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -