GophHub - go4retro/tcpser/src/ip232.c


Raw File

    1	#include <sys/socket.h>   // for recv...
    2	#include <stdlib.h>       // for exit...
    3	#include <sys/file.h>
    4	#include <unistd.h>
    5	#include <termios.h>
    6	#include <stdio.h>
    7	#include <fcntl.h>
    8	#include <sys/ioctl.h>
    9	#include <pthread.h>
   10	#include <sys/select.h>
   11	
   12	#include "util.h"
   13	#include "debug.h"
   14	#include "dce.h"
   15	#include "ip.h"
   16	#include "ip232.h"
   17	
   18	void *ip232_thread(void *arg) {
   19	  dce_config *cfg = (dce_config *)arg;
   20	  int rc;
   21	  unsigned char buf[256];
   22	
   23	  fd_set readfs;
   24	  int max_fd = 0;
   25	
   26	  LOG_ENTER();
   27	  for (;;) {
   28	    FD_ZERO(&readfs);
   29	    FD_SET(cfg->dp[1][0], &readfs);
   30	    max_fd = cfg->dp[1][0];
   31	    FD_SET(cfg->sSocket, &readfs);
   32	    max_fd = MAX(max_fd, cfg->sSocket);
   33	    LOG(LOG_ALL, "Waiting for incoming ip232 connections");
   34	    rc = select(max_fd + 1, &readfs, NULL, NULL, NULL);
   35	
   36	    if (rc < 0) {
   37	      // handle error
   38	    } else {
   39	      if (FD_ISSET(cfg->dp[1][0], &readfs)) {  // pipe
   40	        rc = readPipe(cfg->dp[1][0], buf, sizeof(buf) - 1);
   41	        LOG(LOG_DEBUG, "ip232 thread notified");
   42	      }
   43	      if (FD_ISSET(cfg->sSocket, &readfs)) {  // ip connection
   44	        LOG(LOG_DEBUG, "Incoming ip232 connection");
   45	        rc = ip_accept(cfg->sSocket);
   46	        if(cfg->is_connected) {
   47	          LOG(LOG_DEBUG, "Already have ip232 connection, rejecting new");
   48	          // already have a connection... accept and close
   49	          if(rc > -1) {
   50	            close(rc);
   51	          }
   52	        } else {
   53	          if(rc > -1) {
   54	            cfg->ofd = rc;
   55	            cfg->ifd = rc;
   56	            cfg->is_connected = TRUE;
   57	            cfg->ip232_dtr = FALSE;
   58	            cfg->ip232_dcd = FALSE;
   59	          }
   60	        }
   61	      }
   62	    }
   63	  }
   64	  LOG_EXIT();
   65	}
   66	
   67	int ip232_init_conn(dce_config *cfg) {
   68	  int rc = -1;
   69	
   70	  LOG_ENTER();
   71	  LOG(LOG_INFO, "Opening ip232 device");
   72	  if(cfg->tty[0] == '-') { // use STDIN/STDOUT
   73	    cfg->ofd = STDOUT_FILENO;
   74	    cfg->ifd = STDIN_FILENO;
   75	    cfg->is_connected = TRUE;
   76	    cfg->ip232_dtr = FALSE;
   77	    cfg->ip232_dcd = FALSE;
   78	  } else {
   79	    rc = ip_init_server_conn(cfg->tty, 25232);
   80	
   81	    if (rc < 0) {
   82	      ELOG(LOG_FATAL, "Could not initialize ip232 server socket");
   83	      exit(-1);
   84	    }
   85	    if(-1 == pipe(cfg->dp[0])) {
   86	      ELOG(LOG_FATAL, "ip232 thread incoming IPC pipe could not be created");
   87	      exit(-1);
   88	    }
   89	
   90	    if(-1 == pipe(cfg->dp[1])) {
   91	      ELOG(LOG_FATAL, "ip232 thread outgoing IPC pipe could not be created");
   92	      exit(-1);
   93	    }
   94	
   95	    cfg->sSocket = rc;
   96	    cfg->is_connected = FALSE;
   97	    spawn_thread(ip232_thread, (void *)cfg, "IP232");
   98	  }
   99	  LOG(LOG_INFO, "ip232 device configured");
  100	  LOG_EXIT();
  101	  return 0;
  102	}
  103	
  104	
  105	int ip232_set_flow_control(dce_config *cfg, int status) {
  106	  return 0;
  107	}
  108	
  109	int ip232_get_control_lines(dce_config *cfg) {
  110	
  111	  return ((cfg->is_connected ? DCE_CL_LE : 0)
  112	          | ((cfg->is_connected && cfg->ip232_dtr) ? DCE_CL_DTR : 0)
  113	         );
  114	}
  115	
  116	int ip232_set_control_lines(dce_config *cfg, int state) {
  117	  int dcd;
  118	  int ri;
  119	  unsigned char cmd[2];
  120	
  121	  dcd = (state & DCE_CL_DCD) ? TRUE : FALSE;
  122	  ri = (state & DCE_CL_RI) ? TRUE : FALSE;
  123	  LOG(LOG_DEBUG, "ip232 control line state dcd:%x ri:%x", dcd, ri);
  124	  if ((dcd != cfg->ip232_dcd) || (ri != cfg->ip232_ri)) {
  125	    LOG(LOG_DEBUG, "reconfiguring virtual DCD/RI");
  126	    cfg->ip232_dcd = dcd;
  127	    cfg->ip232_ri = ri;
  128	    if (cfg->is_connected) {
  129	      LOG(LOG_DEBUG, "Sending data");
  130	      cmd[0] = 255;
  131	      cmd[1] = (dcd ? IP232_DCD : 0) | (ri ? IP232_RI : 0);
  132	      write(cfg->ofd, cmd, sizeof(cmd));
  133	    }
  134	  }
  135	  return 0;
  136	}
  137	
  138	int ip232_write(dce_config *cfg, unsigned char* data, int len) {
  139	  int retval;
  140	  int i = 0;
  141	  int double_iac = FALSE;
  142	  unsigned char text[1024];
  143	  int text_len = 0;
  144	
  145	  log_trace(TRACE_MODEM_OUT, data, len);
  146	  retval = len;
  147	  if (cfg->is_connected) {
  148	    while(i < len) {
  149	      if (double_iac) {
  150	        text[text_len++] = 255;
  151	        double_iac = FALSE;
  152	        i++;
  153	      } else {
  154	        if(255 == data[i]) {
  155	          text[text_len++] = 255;
  156	          double_iac = TRUE;
  157	        } else {
  158	          text[text_len++] = data[i++];
  159	        }
  160	      }
  161	
  162	      if(text_len == sizeof(text)) {
  163	        retval = write(cfg->ofd, text, text_len);
  164	        text_len = 0;
  165	      }
  166	    }
  167	    if(text_len) {
  168	      retval = write(cfg->ofd, text, text_len);
  169	    }
  170	  }
  171	  return retval;
  172	}
  173	
  174	int ip232_read(dce_config *cfg, unsigned char *data, int len) {
  175	  int res;
  176	  //int rc;
  177	  unsigned char buf[256];
  178	  int i = 0;
  179	  unsigned char ch;
  180	  int text_len = 0;
  181	
  182	  LOG_ENTER();
  183	  if (len > sizeof(buf)) {
  184	    LOG(LOG_FATAL, "ip232_read: len > sizeof(buf)");
  185	    exit(-1);
  186	  }
  187	
  188	  if (cfg->is_connected) {
  189	    res = recv(cfg->ifd, buf, len, 0);
  190	    if (0 >= res) {
  191	      LOG(LOG_INFO, "No ip232 socket data read, assume closed peer");
  192	      ip_disconnect(cfg->ofd);
  193	      cfg->is_connected = FALSE;
  194	    } else {
  195	      LOG(LOG_DEBUG, "Read %d bytes from ip232 socket", res);
  196	      log_trace(TRACE_MODEM_IN, buf, res);
  197	
  198	      while(i < res) {
  199	        ch = buf[i];
  200	        if (cfg->ip232_iac) {
  201	          cfg->ip232_iac = FALSE;
  202	          switch (ch) {
  203	            case 0:
  204	              cfg->ip232_dtr = FALSE;
  205	              LOG(LOG_DEBUG, "Virtual DTR line down");
  206	              break;
  207	            case 1:
  208	              cfg->ip232_dtr = TRUE;
  209	              LOG(LOG_DEBUG, "Virtual DTR line up");
  210	              break;
  211	            case 255:
  212	              data[text_len++] = 255;
  213	              break;
  214	          }
  215	        } else {
  216	          if (255 == ch) {
  217	            cfg->ip232_iac = TRUE;
  218	          } else {
  219	            data[text_len++] = ch;
  220	          }
  221	        }
  222	        i++;
  223	      }
  224	    }
  225	  }
  226	  LOG_EXIT();
  227	  return text_len;
  228	}
  229	

Generated by GNU Enscript 1.6.6, and GophHub 1.3.