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

📄 conn.c

📁 MODBUS/TCP to RS-232/485 MODBUS/RTU gateway server
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * OpenMODBUS/TCP to RS-232/485 MODBUS RTU gateway * * conn.c - connections management procedures * * Copyright (c) 2002-2003, Victor Antonovich (avmlink@vlink.ru) *  * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: *  * - Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. *  * - Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. *  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * $Id: conn.c,v 1.1.1.1 2003/09/13 20:38:33 kapyar Exp $ */#include "conn.h"#include "queue.h"#include "state.h"/* global variables */extern int server_sd;extern queue_t queue;extern ttydata_t tty;extern cfg_t cfg;conn_t *actconn; /* last active connection */int max_sd; /* major descriptor in the select() sets */void conn_tty_start(ttydata_t *tty, conn_t *conn);ssize_t conn_read(int d, void *buf, size_t nbytes);ssize_t conn_write(int d, void *buf, size_t nbytes);int conn_select(int nfds,                 fd_set *readfds, fd_set *writefds, fd_set *exceptfds,                struct timeval *timeout);#define FD_MSET(d, s) do { FD_SET(d, s); max_sd = MAX(d, max_sd); } while (0);/* * Connections startup initialization * Parameters: none * Return: RC_OK in case of success, RC_ERR otherwise */intconn_init(void){  /* tty device initialization */#ifdef  TRXCTL  tty_init(&tty, cfg.ttyport, cfg.ttyspeed, cfg.trxcntl);#else  tty_init(&tty, cfg.ttyport, cfg.ttyspeed);#endif  if (tty_open(&tty) != RC_OK)  {#ifdef LOG    log(0, "conn_init():"           " can't open tty device %s (%s)",           cfg.ttyport, strerror(errno));#endif    return RC_ERR;  }  state_tty_set(&tty, TTY_READY);    /* create server socket */  if ((server_sd =         sock_create_server("", cfg.serverport, TRUE)) < 0)  {#ifdef LOG    log(0, "conn_init():"           " can't create listen() socket (%s)",           strerror(errno));#endif    return RC_ERR;  }    /* connections queue initialization */  queue_init(&queue);    return RC_OK;}/* * Open new client connection * Parameters: none * Return: none */voidconn_open(void){  int sd;  conn_t *newconn;  struct sockaddr_in rmt_addr;    if ((sd = sock_accept(server_sd, &rmt_addr, TRUE)) == RC_ERR)  { /* error in conn_accept() */#ifdef LOG    log(0, "conn_open(): error in accept() (%s)", strerror(errno));#endif    return;  }#ifdef LOG  log(2, "conn_open(): accepting connection from %s",         inet_ntoa(rmt_addr.sin_addr));#endif  /* compare descriptor of connection with FD_SETSIZE */  if (sd >= FD_SETSIZE)  {#ifdef LOG    log(1, "conn_open(): FD_SETSIZE limit reached,"           " connection from %s will be dropped",           inet_ntoa(rmt_addr.sin_addr));#endif    close(sd);    return;  }  /* check current number of connections */  if (queue.len == cfg.maxconn)  {#ifdef LOG    log(1, "conn_open(): number of connections limit reached,"           " connection from %s will be dropped",           inet_ntoa(rmt_addr.sin_addr));#endif    close(sd);    return;  }  /* enqueue connection */  newconn = queue_new_elem(&queue);  newconn->sd = sd;  memcpy((void *) &newconn->sockaddr,          &rmt_addr, sizeof(struct sockaddr_in));  state_conn_set(newconn, CONN_HEADER);}/* * Close client connection * Parameters: CONN - ptr to connection to close * Return: pointer to next queue element */conn_t *conn_close(conn_t *conn){  conn_t *nextconn;#ifdef LOG  log(2, "conn_close(): closing connection from %s",         inet_ntoa(conn->sockaddr.sin_addr));#endif  /* close socket */  close(conn->sd);  /* get pointer to next element */  nextconn = queue_next_elem(&queue, conn);  /* dequeue connection */  queue_delete_elem(&queue, conn);  if (actconn == conn) actconn = nextconn;  return nextconn;}/* * Start tty transaction * Parameters: TTY - ptr to tty structure,  *             CONN - ptr to active connection * Return: none */voidconn_tty_start(ttydata_t *tty, conn_t *conn){  (void)memcpy((void *)tty->txbuf,                (void *)(conn->buf + HDRSIZE),               MB_HDR(conn->buf, MB_LENGTH_L));  modbus_crc_write(tty->txbuf, MB_HDR(conn->buf, MB_LENGTH_L));  tty->txlen = MB_HDR(conn->buf, MB_LENGTH_L) + CRCSIZE;  state_tty_set(tty, TTY_RQST);  actconn = conn;}/* * Read() wrapper. Read nomore BYTES from descriptor D in buffer BUF * Return: number of successfully readed bytes, *         RC_ERR in case of error. */ssize_tconn_read(int d, void *buf, size_t nbytes){  int rc;  do  { /* trying read from descriptor while breaked by signals */     rc = read(d, buf, nbytes);  } while (rc == -1 && errno == EINTR);  return (rc < 0) ? RC_ERR : rc;}/* * Write() wrapper. Write nomore BYTES to descriptor D from buffer BUF * Return: number of successfully written bytes, *         RC_ERR in case of error. */ssize_tconn_write(int d, void *buf, size_t nbytes){  int rc;  do  { /* trying write to descriptor while breaked by signals */     rc = write(d, buf, nbytes);  } while (rc == -1 && errno == EINTR);  return (rc < 0) ? RC_ERR : rc;}#if 0/* * Select() wrapper with signal checking. * Return: number number of ready descriptors, *         RC_ERR in case of error. */intconn_select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,            struct timeval *timeout){  int rc;  do  { /* trying to select() while breaked by signals */     rc = select(nfds, readfds, writefds, exceptfds, timeout);  } while (rc == -1 && errno == EINTR);  return (rc < 0) ? RC_ERR : rc;}#endif/* * Connections serving loop * Parameters: none * Return: none */voidconn_loop(void){  int rc, max_sd, len, min_timeout;  fd_set sdsetrd, sdsetwr;  struct timeval ts, tts, t_out;  unsigned long tval, tout_sec, tout = 0ul;  conn_t *curconn = NULL;  while (TRUE)  {    /* check for the signals */    if (sig_flag) sig_exec();          /* update FD_SETs */    FD_ZERO(&sdsetrd);    max_sd = server_sd;    FD_MSET(server_sd, &sdsetrd);    FD_ZERO(&sdsetwr);    /* update FD_SETs by TCP connections */    len = queue.len;    curconn = queue.beg;    min_timeout = cfg.conntimeout;    while (len--)    {      switch (curconn->state)      {        case CONN_HEADER:        case CONN_RQST:          FD_MSET(curconn->sd, &sdsetrd);          break;        case CONN_RESP:          FD_MSET(curconn->sd, &sdsetwr);          break;      }      min_timeout = MIN(min_timeout, curconn->timeout);      curconn = queue_next_elem(&queue, curconn);    }        /* update FD_SETs by tty connection */    FD_MSET(tty.fd, &sdsetrd);    if (tty.state == TTY_RQST) FD_MSET(tty.fd, &sdsetwr);    if (tty.timer)

⌨️ 快捷键说明

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