1 #include // for recv... 2 #include // for exit... 3 #include 4 #include 5 #include 6 #include 7 #include 8 #include 9 #include 10 #include 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 }