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

📄 seport.c

📁 功能丰富的串口通讯程序
💻 C
📖 第 1 页 / 共 2 页
字号:
intMdmSetGetStopBits(bits)     int             bits;{#if HAVE_TERMIOS || HAVE_TERMIO  if (bits != -1) {    switch (bits) {    case 1:      pmode.c_cflag &= ~CSTOPB;      break;    case 2:      pmode.c_cflag |= CSTOPB;      break;    default:      SeErrorF("invalid number of stop bits: %d", bits, "", "");      return -1;    }    if (mfd != -1)      io_set_attr(mfd, &pmode);  }  if (mfd != -1)    io_get_attr(mfd, &pmode);  if (pmode.c_cflag & CSTOPB)    return 2;  else    return 1;#else#if !HAVE_SGTTYB  if (mfd != -1)    io_set_attr(mfd, &pmode);  return 1;#endif#endif}/* * Get/set the baud rate of the modem port. If the port hasn't been opened * yet, just store in pmode for mopen() to use when it opens the port. */longmbaud(s)     char           *s;{#if USE_NONSTD_BAUD#ifdef linux  static struct serial_struct ser_io;  if (ioctl(mfd, TIOCGSERIAL, &ser_io) < 0) {    SePError("Could not get linux serial info");    return -1;  }#endif#endif  if (s != NULL) {    /* this gives a more limited, realistic */    switch (atol(s)) {	       /* range than in sgtty.h */    case 300:      baudrate = B300;      break;    case 1200:      baudrate = B1200;      break;    case 2400:      baudrate = B2400;      break;    case 4800:      baudrate = B4800;      break;    case 9600:      baudrate = B9600;      break;    case 19200:      baudrate = B19200;      break;    case 38400:      baudrate = B38400;#if USE_NONSTD_BAUD#ifdef linux      ser_io.flags &= ~ASYNC_SPD_MASK;#endif#endif      break;#if USE_NONSTD_BAUD#ifdef linux    case 57600:      baudrate = B38400;      ser_io.flags &= ~ASYNC_SPD_MASK;      ser_io.flags |= ASYNC_SPD_HI;      break;    case 115200:      baudrate = B38400;      ser_io.flags &= ~ASYNC_SPD_MASK;      ser_io.flags |= ASYNC_SPD_VHI;      break;#endif#endif    default:      return (-1);    }    io_set_speed(&pmode, baudrate);    if (mfd != -1) {      io_set_attr(mfd, &pmode);#if USE_NONSTD_BAUD#ifdef linux      if (baudrate == B38400)	if (ioctl(mfd, TIOCSSERIAL, &ser_io) < 0) {	  SePError("Could not set linux serial info");	  return -1;	}#endif#endif    }  }  if (mfd != -1)    io_get_attr(mfd, &pmode);  switch (io_get_speed(&pmode)) {  case B300:    return (300);  case B1200:    return (1200);  case B2400:    return (2400);  case B4800:    return (4800);  case B9600:    return (9600);  case B19200:    return (19200);  case B38400:#if USE_NONSTD_BAUD#ifdef linux    if (mfd != -1)      if (ioctl(mfd, TIOCGSERIAL, &ser_io) < 0) {		SePError("Could not get linux serial info");		return -1;      }    if ((ser_io.flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)      return 115200;    else if ((ser_io.flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)      return 57600;    else#endif#endif      return 38400;  }  SeError("Consistency error in baud rate");  return -1;}/* * The following routine is used to hang up the modem.  This is accomplished * by setting the baud rate to 0.  According to my documentation on termio, * setting the baud rate to zero will result in DTR not being asserted. This * hangs up some (most?) modems.  If not, the second part of the routine * sends the Hayes modem "escape" and then a hangup command. */voidMdmHangup(){  int terminalWasActive;  if (mfd == -1) return;  terminalWasActive = SuspContTerminal(TERM_SUSPEND);  if (qres.hangupViaDTR) {    io_set_speed(&pmode, B0);	/* set baud 0 (drop DTR) */    io_set_attr(mfd, &pmode);    sleep(1);					/* wait a second */    io_set_speed(&pmode, baudrate);	/* reset baud rate */    io_set_attr(mfd, &pmode);  }  else {						/* use Hayes command */    sleep(2);					/* allow for "escape guard time" */    MdmPutString(qres.modemAttentionString); /* send modem escape command */    sleep(3);					/* more "escape guard time" */    MdmPutString(qres.modemHangupString); /* send hangup command */  }  MdmPurge();  if (terminalWasActive) SuspContTerminal(TERM_CONTINUE);    UpdateStatusBox(NULL);}  /* * Opens the modem port and configures it. Returns 0 for success or -1 on * error. */intOpenModem(modem)	 String modem;{  int             LockModem(),                  UnlockModem();  void            MdmIOFlush();  int             oldFlags;  if (modem == NULL || modem[0] == '\0') return ERR_MDM_NOMODEM;  if (LockModem(modem)) return ERR_MDM_LOCKED;  /* Need O_NDELAY to get the file open before we have carrier */  if ((mfd = open(modem, O_RDWR | O_NDELAY)) < 0) 	{UnlockModem(modem); return ERR_MDM_OPENFAILED;}  /* Now, we must reset the O_NDELAY mode so that read() works correctly */  if (((oldFlags = fcntl(mfd, F_GETFL, 0)) == -1) ||      (fcntl(mfd, F_SETFL, oldFlags & ~O_NDELAY) == -1)) 	{UnlockModem(modem); return ERR_MDM_RESETFLAGSFAILED;}#if HAVE_SGTTYB  if (ioctl(mfd, TIOCEXCL) < 0)    SePError("exclusive-use");#endif  mport(modem);  MdmIOFlush();  MdmSaveRestoreAttr(ATTR_SAVE);  SetInitialModemAttr();  io_set_attr(mfd, &pmode);  GetModemStat(1);  if (mbaud(qres.defaultBPS) == -1)    se_warningf("invalid default BPS value: %s", qres.defaultBPS, "", "");  if (MdmSetGetCSize(qres.defaultBits) < 0)    se_warningf("invalid default number of bits: %s", qres.defaultBits, 				"", "");  if (MdmSetGetParity(qres.defaultParity) < 0)    se_warningf("invalid default parity value: %s", qres.defaultParity, 				"", "");  if (MdmSetGetStopBits(qres.defaultStopBits) < 0)    se_warningf("invalid default number of stop bits: %s",				qres.defaultStopBits, "", "");  return 0;}voidShowOpenModemErrMsg(modemName, retStatus)	 String    modemName;	 int       retStatus;{  switch(retStatus) {  case ERR_MDM_NOMODEM:	SeError("No Modem Specified");	break;  case ERR_MDM_LOCKED:	SeError(FmtString("Modem ``%s'' is Locked", modemName, "", ""));	break;  case ERR_MDM_OPENFAILED:	SePError(FmtString("Unable to Open Modem ``%s''", modemName, "", ""));	break;  case ERR_MDM_RESETFLAGSFAILED:	SePError(FmtString("Unable to Reset Flags for Modem ``%s''", 					   modemName, "", ""));	break;  default:	SeError(FmtString("Unknown Error While Openeong Modem ``%s''", 					  modemName, "", ""));	break;  }}intCloseModem(){  if (mfd == -1) return -1;  MdmSaveRestoreAttr(ATTR_RESTORE);  close(mfd);  return 0;}/* * Attach standard input and output to the modem port. This only gets called * after a fork by the child process; which then exec's a program that uses * standard i/o for some data transfer protocol. (To put this here is * actually a kludge, but I wanted to keep the modem-specific stuff in a * black box.) */voidmattach(){  extern int dup2();  /*   * attach standard i/o to port   */  dup2(mfd, 0);					/* close local stdin and connect to port */  dup2(mfd, 1);					/* close local stdout and connect to port */  close(mfd);					/* close the old port descriptor */}/* ------------------------------------------------------------ * Routines to read from the modem. *//* * MdmReadStr: reads a bunch of characters from the modem. */intMdmReadStr(buf)	 char           *buf;{  return TtyReadStr(mfd, buf);}/* * MdmReadChar: reads one character from the modem. */charMdmReadChar(readChar)	 char           *readChar;{  return TtyReadChar(mfd, readChar);}intMdmTimedReadChar(readChar, expireTime)	 char           *readChar;     int             expireTime;{  return TtyTimedReadChar(mfd, readChar, expireTime);}/* * MdmReadLine: reads one line from the modem. */intMdmReadLine(buf)	 char           *buf;{  return TtyReadLine(mfd, buf);}intMdmTimedWaitFor(expectedString, waitTime)	 char           *expectedString;     int             waitTime;{  return TtyTimedWaitFor(mfd, expectedString, waitTime);}/* * MdmPurge: throws away all incoming characters until no more are sent. */voidMdmPurge(){  char            c;  while (MdmTimedReadChar(&c, 1) >= 0);}#ifdef retiredintreadbyte(seconds)     int             seconds;{  return trminp(mfd, seconds);}#endif/* *    Output a byte to the modem port. All data sent to the modem *    is output through this routine. */voidsendbyte(ch)     int             ch;{  char            c = ch & 0xff;  if (write(mfd, &c, 1) < 0)    SePError("character write");}voidsendf_slowly(format, a, b, c)     char           *format,                    *a,                    *b,                    *c;{  char            buffer[SM_BUF];  sprintf(buffer, format, a, b, c);  send_slowly(buffer);}voidsend_slowly(s)     char           *s;{  while (*s) {    sendbyte(*s++);    /*     * avoid busy waiting by using usleep if available. adjust MDELAY if     * you're having trouble     */    usleep(MDELAY);  }}/* * lock_tty() returns non-zero if the lock file exists (prevents Seyon from * running). * * unlock_tty() deletes the lock file. * * Simple, eh? */char            lckf[SM_BUF];char            ltmp[SM_BUF];pid_t           lockPid;intLockModem(modem)	 String modem;{  strcpy(modem_port, modem);  return lock_tty();}intUnlockModem(modem)	 String modem;{  unlock_tty();  return 0;}intlock_tty(){  int             lfd;  pid_t           pid,                  lckpid;  char           *modemname;#if LF_USE_ASCII_PID  char            pidstr[20],                  lckpidstr[20];  int             nb;#endif#if LF_USE_DEV_NUMBERS  struct stat  mbuf;#endif  /* Get our PID, and initialize the filename strings */  pid = getpid();#if !LF_USE_DEV_NUMBERS  modemname = strrchr(modem_port, '/');  sprintf(lckf, "%s/%s%s", LF_PATH, LF_PREFIX, 		  (modemname ? (modemname + 1) : modem_port));#else  if(stat(modem_port, &mbuf) < 0) {	SePErrorF("could not stat modem port %s", modem_port, "", "");	return -1;  }  sprintf(lckf,"%s/%s%03u.%03u.%03u", LF_PATH, LF_PREFIX, major(mbuf.st_dev),		  major(mbuf.st_rdev), minor(mbuf.st_rdev));#endif /* LF_USE_DEV_NUMBERS */  sprintf(ltmp, "%s/%s%d", LF_PATH, "LTMP.", pid);  /* Create the LTMP.<pid> file and scribble our PID in it */  unlink(ltmp);  if ((lfd = creat(ltmp, 0644)) == -1) {    SePErrorF("Could not create temporary lock file %s", ltmp, "", "");    return -1;  }#if LF_USE_ASCII_PID  sprintf(pidstr, "%10d\n", pid);  write(lfd, pidstr, 11);#else  write(lfd, (char*)&pid, sizeof(pid));#endif  close(lfd);  /*   * Attempt to link directly - if it works, we're done.   */relink:  if (link(ltmp, lckf) == 0) {    unlink(ltmp);    lockPid = pid;    return 0;  }  /*   * Oh brother, there's a LCK..* file already; we must now expend effort to   * learn if it's stale or not.   */  if ((lfd = open(lckf, O_RDONLY)) != -1) {#if LF_USE_ASCII_PID    for (nb = 0; nb < 20 && read(lfd, lckpidstr + nb, sizeof(char)); nb++);    if (nb) {      lckpid = atol(lckpidstr);#else    if (read(lfd, (char *)&lckpid, sizeof(lckpid)) == sizeof(lckpid)) {#endif      lockPid = (pid_t) lckpid;      if (kill(lckpid, 0) == 0 || errno != ESRCH) {		SeErrorF("Device %s is locked by process %d", modem_port, lckpid, "");		unlink(ltmp);		return -1;      }    }  }  /*   * The LCK..* file was stale.  Remove and retry.   */  if (unlink(lckf)) {    SePErrorF("Unable to unlink stale lock file \"%s\"", lckf, "", "");    unlink(ltmp);    return -1;  }  goto relink;  /* NOTREACHED */}voidunlock_tty(){  /* Don't remove the lock file unless it's the one we created */  if (getpid() == lockPid)    unlink(lckf);}

⌨️ 快捷键说明

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