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

📄 conn.c

📁 MODBUS/TCP to RS-232/485 MODBUS/RTU gateway server
💻 C
📖 第 1 页 / 共 2 页
字号:
    { /* tty.timer is non-zero in TTY_PAUSE, TTY_RESP states */      t_out.tv_sec = tty.timer / 1000000ul;      t_out.tv_usec = tty.timer % 1000000ul;    }    else    {       t_out.tv_usec = 0ul;      if (cfg.conntimeout)        t_out.tv_sec = min_timeout; /* minor timeout value */      else         t_out.tv_sec = 10ul; /* XXX default timeout value */    }    (void)gettimeofday(&ts, NULL); /* make timestamp */ #ifdef DEBUG    log(7, "conn_loop(): select(): max_sd = %d, t_out = %06lu:%06lu ",            max_sd, t_out.tv_sec, t_out.tv_usec);#endif    rc = select(max_sd + 1, &sdsetrd, &sdsetwr, NULL, &t_out);    if (rc < 0)    { /* some error caused while select() */      if (errno == EINTR) continue; /* process signals */      /* unrecoverable error in select(), exiting */#ifdef LOG      log(0, "conn_loop(): error in select() (%s)", strerror(errno));#endif      break;    }    /* calculating elapsed time */        (void)gettimeofday(&tts, NULL);    tval = 1000000ul * (tts.tv_sec - ts.tv_sec) +                       (tts.tv_usec - ts.tv_usec);        /* modify tty timer */    if (tty.timer)    { /* tty timer is active */      if (tty.timer <= tval)        switch (tty.state)        { /* timer expired */          case TTY_PAUSE:            /* inter-request pause elapsed */            /* looking for connections in CONN_TTY state */            curconn = state_conn_search(&queue, actconn, CONN_TTY);            if (curconn != NULL)              conn_tty_start(&tty, curconn);            else              state_tty_set(&tty, TTY_READY);            break;          case TTY_RESP:            /* checking for received data */            if (FD_ISSET(tty.fd, &sdsetrd)) break;            /* response timeout handling */            if (!tty.ptrbuf)            {/* there no bytes received */#ifdef DEBUG              log(5, "tty: response timeout", tty.ptrbuf);#endif              if (!tty.trynum)                modbus_ex_write(actconn->buf, MB_EX_TIMEOUT);              else              { /* retry request */#ifdef DEBUG                log(5, "tty: attempt to retry request (%u of %u)",                       cfg.maxtry - tty.trynum + 1, cfg.maxtry);#endif                state_tty_set(&tty, TTY_RQST);                break;              }            }            else             { /* some data received */#ifdef DEBUG            log(5, "tty: response readed (total %d bytes)", tty.ptrbuf);#endif              if (tty.ptrbuf >= MB_MIN_LEN &&                      modbus_crc_correct(tty.rxbuf, tty.ptrbuf))              { /* received response is correct, make OpenMODBUS response */#ifdef DEBUG                log(5, "tty: response is correct");#endif                (void)memcpy((void *)(actconn->buf + HDRSIZE),                             (void *)tty.rxbuf, tty.ptrbuf - CRCSIZE);                WORD_WR_BE(actconn->buf + MB_LENGTH_H, tty.ptrbuf - CRCSIZE);              }              else              {                /* received response is incomplete or CRC failed */#ifdef DEBUG                log(5, "tty: response is incorrect");#endif                if (!tty.trynum)                  modbus_ex_write(actconn->buf, MB_EX_CRC);                else                { /* retry request */#ifdef DEBUG                  log(5, "tty: attempt to retry request (%u of %u)",                         cfg.maxtry - tty.trynum + 1, cfg.maxtry);#endif                  state_tty_set(&tty, TTY_RQST);                  break;                }              }            }            /* switch connection to response state */            state_conn_set(actconn, CONN_RESP);            /* make inter-request pause */            state_tty_set(&tty, TTY_PAUSE);            break;        }      else tty.timer -= tval;    }        if (cfg.conntimeout)    { /* expire staled connections */      tout += tval;      tout_sec = tout / 1000000ul;      if (tout_sec)      { /* at least one second elapsed, check for staled connections */        len = queue.len;        curconn = queue.beg;        while (len--)        {          curconn->timeout -= tout_sec;          if (curconn->timeout <= 0)          { /* timeout expired */            if (curconn->state == CONN_TTY)            { /* deadlock in CONN_TTY state, exiting */#ifdef LOG              log(0, "conn[%s]: state CONN_TTY deadlock, exiting!",                     inet_ntoa(curconn->sockaddr.sin_addr));#endif              exit (-1);            }            /* purge connection */#ifdef LOG            log(2, "conn[%s]: timeout, closing connection",                   inet_ntoa(curconn->sockaddr.sin_addr));#endif            curconn = conn_close(curconn);            continue;          }          curconn = queue_next_elem(&queue, curconn);        }        tout = tout % 1000000ul;      }    }        if (rc == 0)      continue;	/* timeout caused, we will do select() again */    /* checking for pending connections */    if (FD_ISSET(server_sd, &sdsetrd)) conn_open();    /* tty processing */    if (tty.state == TTY_RQST)      if (FD_ISSET(tty.fd, &sdsetwr))      {        rc = conn_write(tty.fd, tty.txbuf + tty.ptrbuf,                        tty.txlen - tty.ptrbuf);        if (rc <= 0)        { /* error - we can't continue... */#ifdef LOG          log(0, "tty: error in write() (%s)", strerror(errno));#endif          break; /* exiting... */        }#ifdef DEBUG        log(7, "tty: written %d bytes", rc);#endif        tty.ptrbuf += rc;        if (tty.ptrbuf == tty.txlen)        { /* request transmitting completed, switch to TTY_RESP */#ifdef DEBUG          log(7, "tty: request written (total %d bytes)", tty.txlen);#endif          state_tty_set(&tty, TTY_RESP);        }      }        if (FD_ISSET(tty.fd, &sdsetrd))    {      if (tty.state == TTY_RESP)      {        rc = conn_read(tty.fd, tty.rxbuf + tty.ptrbuf,                       tty.rxlen - tty.ptrbuf);        if (rc <= 0)        { /* error - we can't continue... */#ifdef LOG          log(0, "tty: error in read() (%s)", strerror(errno));#endif          break; /* exiting... */        }#ifdef DEBUG          log(7, "tty: readed %d bytes", rc);#endif        tty.ptrbuf += rc;        if (tty.ptrbuf == tty.rxlen)        { /* XXX still generating error response */          modbus_ex_write(actconn->buf, MB_EX_CRC);          /* switch connection to response state */          state_conn_set(actconn, CONN_RESP);          /* make inter-request pause */          state_tty_set(&tty, TTY_PAUSE);        }        else          /* reset timer */          tty.timer = cfg.respwait * 1000l;      }      else      { /* drop unexpected tty data */        if ((rc = conn_read(tty.fd, tty.rxbuf, BUFSIZE)) <= 0)        { /* error - we can't continue... */#ifdef LOG          log(0, "tty: error in read() (%s)", strerror(errno));#endif          break; /* exiting... */        }#ifdef DEBUG          log(7, "tty: dropped %d bytes", rc);#endif      }    }        /* processing data on the sockets */    len = queue.len;    curconn = queue.beg;    while (len--)    {      switch (curconn->state)      {        case CONN_HEADER:        case CONN_RQST:          if (FD_ISSET(curconn->sd, &sdsetrd))          {            rc = conn_read(curconn->sd,                           curconn->buf + curconn->ctr,                           RQSTSIZE - curconn->ctr);            if (rc <= 0)            { /* error - drop this connection and go to next queue element */              curconn = conn_close(curconn);              break;            }            curconn->ctr += rc;            if (curconn->state == CONN_HEADER)              if (curconn->ctr >= HDRSIZE)              { /* header received completely */                if (modbus_check_header(curconn->buf) != RC_OK)                { /* header is damaged, drop connection */                  curconn = conn_close(curconn);                  break;                }                state_conn_set(curconn, CONN_RQST);              }            if (curconn->state == CONN_RQST)              if (curconn->ctr >=                     HDRSIZE + MB_HDR(curconn->buf, MB_LENGTH_L))              { /* ### packet received completely ### */                state_conn_set(curconn, CONN_TTY);                if (tty.state == TTY_READY)                  conn_tty_start(&tty, curconn);              }          }          curconn = queue_next_elem(&queue, curconn);          break;        case CONN_RESP:          if (FD_ISSET(curconn->sd, &sdsetwr))          {            rc = conn_write(curconn->sd,                            curconn->buf + curconn->ctr,                            MB_HDR(curconn->buf, MB_LENGTH_L) +                             HDRSIZE - curconn->ctr);            if (rc <= 0)            { /* error - drop this connection and go to next queue element */              curconn = conn_close(curconn);              break;            }            curconn->ctr += rc;            if (curconn->ctr == (MB_HDR(curconn->buf, MB_LENGTH_L) + HDRSIZE))              state_conn_set(curconn, CONN_HEADER);          }          curconn = queue_next_elem(&queue, curconn);          break;      } /* switch (curconn->state) */    } /* while (len--) */  } /* while (TRUE) */    /* XXX some cleanup must be here */}

⌨️ 快捷键说明

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