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

📄 serchan.cxx

📁 sloedgy open sip stack source code
💻 CXX
📖 第 1 页 / 共 2 页
字号:
/*
 * serchan.cxx
 *
 * Asynchronous serial I/O channel class implementation.
 *
 * Portable Windows Library
 *
 * Copyright (c) 1993-1998 Equivalence Pty. Ltd.
 *
 * The contents of this file are subject to the Mozilla Public License
 * Version 1.0 (the "License"); you may not use this file except in
 * compliance with the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS"
 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
 * the License for the specific language governing rights and limitations
 * under the License.
 *
 * The Original Code is Portable Windows Library.
 *
 * The Initial Developer of the Original Code is Equivalence Pty. Ltd.
 *
 * Portions are Copyright (C) 1993 Free Software Foundation, Inc.
 * All Rights Reserved.
 *
 * Contributor(s): ______________________________________.
 *
 * $Log: serchan.cxx,v $
 * Revision 1.1  2006/06/29 04:18:41  joegenbaclor
 * *** empty log message ***
 *
 * Revision 1.32  2005/11/30 12:47:42  csoutheren
 * Removed tabs, reformatted some code, and changed tags for Doxygen
 *
 * Revision 1.31  2005/03/10 03:27:30  dereksmithies
 * Fix an address typo.
 *
 * Revision 1.30  2005/01/03 02:52:52  csoutheren
 * Fixed problem with default speed of serial ports
 * Fixed problem with using obsolete lock directory for serial ports
 *
 * Revision 1.29  2004/07/11 07:56:36  csoutheren
 * Applied jumbo VxWorks patch, thanks to Eize Slange
 *
 * Revision 1.28  2004/02/22 04:06:47  ykiryanov
 * ifdef'd all functions because BeOS don't support it
 *
 * Revision 1.27  2002/11/02 00:32:21  robertj
 * Further fixes to VxWorks (Tornado) port, thanks Andreas Sikkema.
 *
 * Revision 1.26  2002/10/17 13:44:27  robertj
 * Port to RTEMS, thanks Vladimir Nesic.
 *
 * Revision 1.25  2002/10/10 04:43:44  robertj
 * VxWorks port, thanks Martijn Roest
 *
 * Revision 1.24  2002/03/27 06:42:16  robertj
 * Implemented the DTR etc functions and ttya/ttyb strings for sunos,
 *    thanks tommi.korhonen@insta.fi & Raimo Ruokonen <rruokonen@koti.soon.fi>
 *
 * Revision 1.23  2001/09/10 03:03:36  robertj
 * Major change to fix problem with error codes being corrupted in a
 *   PChannel when have simultaneous reads and writes in threads.
 *
 * Revision 1.22  2001/08/11 15:38:43  rogerh
 * Add Mac OS Carbon changes from John Woods <jfw@jfwhome.funhouse.com>
 *
 * Revision 1.21  2001/01/04 17:57:41  rogerh
 * Fix a cut and past error in my previous commit
 *
 * Revision 1.20  2001/01/04 10:28:07  rogerh
 * FreeBSD does not set the Baud Rate with c_cflags. Add the 'BSD' way
 *
 * Revision 1.19  2001/01/03 10:56:01  rogerh
 * CBAUD is not defined on FreeBSD.
 *
 * Revision 1.18  2000/12/29 07:36:18  craigs
 * Finally got working correctly!
 *
 * Revision 1.17  2000/11/14 14:56:24  rogerh
 * Fix #define parameters (fd should be just f)
 *
 * Revision 1.16  2000/11/14 14:52:32  rogerh
 * Fix SET/GET typo error
 *
 * Revision 1.15  2000/11/12 23:30:41  craigs
 * Fixed problems with serial port configuration
 *
 * Revision 1.14  2000/06/21 01:01:22  robertj
 * AIX port, thanks Wolfgang Platzer (wolfgang.platzer@infonova.at).
 *
 * Revision 1.13  2000/04/09 18:19:23  rogerh
 * Add my changes for NetBSD support.
 *
 * Revision 1.12  2000/04/06 12:11:32  rogerh
 * MacOS X support submitted by Kevin Packard
 *
 * Revision 1.11  2000/03/08 12:17:09  rogerh
 * Add OpenBSD support
 *
 * Revision 1.10  1998/12/21 06:08:08  robertj
 * Fixed warning on solaris x86 GNU system.
 *
 * Revision 1.9  1998/11/30 21:51:54  robertj
 * New directory structure.
 *
 * Revision 1.8  1998/11/24 09:39:14  robertj
 * FreeBSD port.
 *
 * Revision 1.7  1998/09/24 04:12:17  robertj
 * Added open software license.
 *
 */
 
#pragma implementation "serchan.h"
#pragma implementation "modem.h"

#include <ptlib.h>
#include <fcntl.h>
#include <signal.h>
#include <sys/ioctl.h>

#if defined(P_LINUX)
#define  TCSETATTR(f,t)  tcsetattr(f,TCSANOW,t)
#define  TCGETATTR(f,t)  tcgetattr(f,t)

#elif defined(P_FREEBSD) || defined(P_OPENBSD) || defined (P_NETBSD) || defined(P_MACOSX) || defined(P_MACOS) || defined(P_RTEMS)
#include <sys/ttycom.h>
#define TCGETA TIOCGETA
#define TCSETAW TIOCSETAW

#elif defined(P_SUN4)
#include <sys/termio.h>
extern "C" int ioctl(int, int, void *);

#elif defined (P_AIX)
#include <sys/termio.h>
#endif


#ifndef  TCSETATTR
#define  TCSETATTR(f,t)  ::ioctl(f,TCSETAW,t)
#endif

#ifndef  TCGETATTR
#define  TCGETATTR(f,t)  ::ioctl(f,TCGETA,t)
#endif

//#define BINARY_LOCK  1
//#define  LOCK_PREFIX  "/var/spool/uucp/LCK.."
#define  LOCK_PREFIX  "/var/lock/LCK.."
#define  DEV_PREFIX  "/dev/"

#define  PORTLISTENV  "PWLIB_SERIALPORTS"
#define  DEV_PREFIX  "/dev/"

#include "../common/serial.cxx"

////////////////////////////////////////////////////////////////
//
//  PSerialChannel
//

void PSerialChannel::Construct()
{
  // set control modes: 9600, N, 8, 1, local line
  baudRate   = 9600;
  dataBits   = 8;
  parityBits = NoParity;
  stopBits   = 1;

#if defined(P_VXWORKS) || defined (__BEOS__)
  PAssertAlways(PUnimplementedFunction);
#else

  // set input mode: ignore breaks, ignore parity errors, do not strip chars,
  // no CR/NL conversion, no case conversion, no XON/XOFF control,
  // no start/stop
  Termio.c_iflag = IGNBRK | IGNPAR;
  Termio.c_cflag = CS8 | CSTOPB | CREAD | CLOCAL;

#if defined(P_FREEBSD) || defined(P_OPENBSD) || defined (P_NETBSD) || defined(P_MACOSX) || defined(P_MACOS)
  Termio.c_ispeed = Termio.c_ospeed = B9600;
#else
  Termio.c_cflag |= B9600;
#endif

  // set output mode: no post process output, 
  Termio.c_oflag = 0;

  // set line discipline
  Termio.c_lflag = 0;

#endif // P_VXWORKS
}

BOOL PSerialChannel::Close()
{
#if defined(P_VXWORKS) || defined (__BEOS__)
  PAssertAlways(PUnimplementedFunction);
  return FALSE;
#else
  if (os_handle >= 0) {

    // delete the lockfile
    PFile::Remove(PString(LOCK_PREFIX) + channelName);

    // restore the original terminal settings
    TCSETATTR(os_handle, &oldTermio);
  }

  return PChannel::Close();
#endif // P_VXWORKS
}


BOOL PSerialChannel::Open(const PString & port, 
                                    DWORD speed,
                                     BYTE data,
                                   Parity parity,
                                     BYTE stop,
                              FlowControl inputFlow,
                              FlowControl outputFlow)
{
  // if the port is already open, close it
  if (IsOpen())
    Close();

//  // check prefix of name
//  if (port.Left(PORT_PREFIX_LEN) != PORT_PREFIX) {
//    lastError = BadParameter;
//    return FALSE;
//  }

//  // check suffix
//  int portnum = (port.Right(port.GetLength()-PORT_PREFIX_LEN)).AsInteger();
//  if ((portnum < PORT_START) || (portnum >= (PORT_START + PORT_COUNT))) {
//    lastError = BadParameter;
//    return FALSE;
//  }

  // save the port name
  channelName = port;

#if defined(P_VXWORKS) || defined (__BEOS__)
  PAssertAlways(PUnimplementedFunction);
  return FALSE;
#else

  // construct lock filename 
  PString lockfilename = PString(LOCK_PREFIX) + port;

  // if the file exists, probe the process to see if it is still running
  if (PFile::Exists(lockfilename)) {
    PFile lockfile(lockfilename, PFile::ReadOnly);

    int lock_pid;
#ifdef BINARY_LOCK
    lockfile.Read(&lock_pid, sizeof(lock_pid));
#else
    char lock_pid_str[20];
    lockfile.Read(lock_pid_str, 20);
    lock_pid = atoi(lock_pid_str);
#endif
    
    // if kill returns 0, then the port is in use
    if (kill(lock_pid, 0) == 0)
      return SetErrorValues(DeviceInUse, EBUSY);

    // remove the lock file
    lockfile.Remove();
  }

  // create new lockfile with our PID
  PFile lockfile(lockfilename, PFile::WriteOnly, PFile::Create);
  int pid = getpid();
#ifdef BINARY_LOCK
  lockfile.Write(&pid, sizeof(pid));
#else
  lockfile << pid;
#endif
  lockfile.Close();

  // attempt to open the device
  PString device_name = PString(DEV_PREFIX) + port;
  if ((os_handle = ::open((const char *)device_name, O_RDWR|O_NONBLOCK|O_NOCTTY)) < 0) {
    ConvertOSError(os_handle);
    Close();
    return FALSE;
  }

  // save the channel name
  channelName = port;

  // save the current port setup
  TCGETATTR(os_handle, &oldTermio);

  // set the default paramaters
  TCSETATTR(os_handle, &Termio);

  // now set the mode that was passed in
  if (!SetSpeed(speed) ||
      !SetDataBits(data) ||
      !SetParity(parity) ||
      !SetStopBits(stop) ||
      !SetInputFlowControl(inputFlow) ||
      !SetOutputFlowControl(outputFlow)) {
    errno = EINVAL;
    ConvertOSError(-1);
    return FALSE;
  }

  ::fcntl(os_handle, F_SETFD, 1);

#endif // P_VXWORKS

  return TRUE;
}

BOOL PSerialChannel::SetSpeed(DWORD newBaudRate)
{
  if (newBaudRate == baudRate)
    return TRUE;

  if (os_handle < 0)
    return TRUE;

#if defined(P_VXWORKS) || defined (__BEOS__)
  PAssertAlways(PUnimplementedFunction);
  return FALSE;
#else

  int baud;

  switch(newBaudRate) {
#ifdef B50
    case 50:
      baud = B50;
      break;
#endif
#ifdef B75
    case 75:
      baud = B75;
      break;
#endif
#ifdef B110
    case 110:
      baud = B110;
      break;
#endif
#ifdef B134
    case 134:
      baud = B134;
      break;
#endif
#ifdef B150
    case 150:
      baud = B150;
      break;
#endif
#ifdef B200
    case 200:
      baud = B200;
      break;
#endif
#ifdef B300
    case 300:
      baud = B300;
      break;
#endif
#ifdef B600
    case 600:
      baud = B600;
      break;
#endif
#ifdef B1200
    case 1200:
      baud = B1200;
      break;
#endif
#ifdef B1800
    case 1800:
      baud = B1800;
      break;
#endif
#ifdef B2400
    case 2400:
      baud = B2400;
      break;
#endif
#ifdef B4800
    case 4800:
      baud = B4800;
      break;
#endif
#ifdef B9600
    case 9600:
    case 0:          // default
      baud = B9600;
      break;

⌨️ 快捷键说明

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