1 #include 2 #include 3 #include 4 #include 5 6 #include "debug.h" 7 #include "serial.h" 8 #include "modem_core.h" 9 #include "ip232.h" // needs modem_core.h 10 #include "dce.h" 11 12 void dce_init_config(dce_config *cfg) { 13 cfg->parity = -1; // parity not yet checked. 14 } 15 16 int detect_parity (int charA, int charT) { 17 int parity, eobits; 18 19 parity = ((charA >> 6) & 2) | (charT >> 7); 20 eobits = gen_parity(charA & 0x7f) << 1 | gen_parity(charT & 0x7f); 21 22 if((parity == 1) || (parity == 2)) { 23 if(parity == eobits) 24 return PARITY_EVEN; 25 else 26 return PARITY_ODD; 27 } else 28 return parity; 29 } 30 31 int dce_connect(dce_config *cfg) { 32 int rc; 33 34 LOG_ENTER(); 35 if (cfg->is_ip232) { 36 rc = ip232_init_conn(cfg); 37 } else { 38 rc = ser_init_conn(cfg->tty, cfg->port_speed); 39 if(-1 < rc) { 40 cfg->is_connected = TRUE; 41 cfg->ofd = rc; 42 cfg->ifd = rc; 43 } 44 } 45 46 LOG_EXIT(); 47 return rc; 48 } 49 50 int dce_set_flow_control(dce_config *cfg, int opts) { 51 int status = 0; 52 int rc = 0; 53 54 LOG_ENTER(); 55 if(opts == 0) { 56 LOG(LOG_ALL, "Setting NONE flow control"); 57 } else { 58 if((opts & MDM_FC_RTS) != 0) { 59 LOG(LOG_ALL, "Setting RTSCTS flow control"); 60 status |= CRTSCTS; 61 } 62 if((opts & MDM_FC_XON) != 0) { 63 status |= (IXON | IXOFF); 64 LOG(LOG_ALL, "Setting XON/XOFF flow control"); 65 } 66 } 67 68 if (cfg->is_ip232) { 69 rc = ip232_set_flow_control(cfg, status); 70 } else { 71 rc = ser_set_flow_control(cfg->ofd, status); 72 } 73 74 LOG_EXIT() 75 return rc; 76 } 77 78 int dce_set_control_lines(dce_config *cfg, int state) { 79 int rc; 80 81 LOG_ENTER(); 82 // if((state & DCE_CL_CTS) != 0) { 83 // LOG(LOG_ALL, "Setting CTS pin high"); 84 // } else { 85 // LOG(LOG_ALL, "Setting CTS pin low"); 86 // } 87 if((state & DCE_CL_DCD) != 0) { 88 LOG(LOG_ALL, "Setting DCD pin high"); 89 } else { 90 LOG(LOG_ALL, "Setting DCD pin low"); 91 } 92 93 if((state & DCE_CL_RI) != 0) { 94 LOG(LOG_ALL, "Setting RI pin high"); 95 } else { 96 LOG(LOG_ALL, "Setting RI pin low"); 97 } 98 99 if (cfg->is_ip232) { 100 rc = ip232_set_control_lines(cfg, state); 101 } else { 102 rc = ser_set_control_lines(cfg->ofd, state); 103 } 104 105 LOG_EXIT(); 106 return rc; 107 } 108 109 int dce_get_control_lines(dce_config *cfg) { 110 int state; 111 112 if (cfg->is_ip232) { 113 state = ip232_get_control_lines(cfg); 114 } else { 115 state = ser_get_control_lines(cfg->ifd); 116 } 117 return state; 118 } 119 120 int dce_check_control_lines(dce_config *cfg) { 121 int state = 0; 122 int new_state = 0; 123 124 LOG_ENTER(); 125 state = dce_get_control_lines(cfg); 126 new_state = state; 127 while(new_state > -1 && state == new_state) { 128 usleep(100000); 129 new_state = dce_get_control_lines(cfg); 130 } 131 132 LOG_EXIT(); 133 return new_state; 134 } 135 136 int dce_write(dce_config *cfg, unsigned char data[], int len) { 137 unsigned char *buf; 138 int rc; 139 int i; 140 141 log_trace(TRACE_SERIAL_OUT, data, len); 142 if (cfg->is_ip232) { 143 return ip232_write(cfg, data, len); 144 } else if(cfg->parity) { 145 buf = malloc(len); // TODO what if malloc fails? 146 memcpy(buf, data, len); 147 148 if(0 < cfg->parity) { 149 for (i = 0; i < len; i++) { 150 buf[i] = apply_parity(data[i], cfg->parity); 151 } 152 } 153 } else { 154 buf = data; 155 } 156 rc = ser_write(cfg->ofd, buf, len); 157 if(cfg->parity) 158 free(buf); 159 return rc; 160 } 161 162 int dce_write_char_raw(dce_config *cfg, unsigned char data) { 163 int rc; 164 165 log_trace(TRACE_SERIAL_OUT, &data, 1); 166 if (cfg->is_ip232) { 167 rc = ip232_write(cfg, &data, 1); 168 } else { 169 rc = ser_write(cfg->ofd, &data, 1); 170 } 171 return rc; 172 } 173 174 int dce_read(dce_config *cfg, unsigned char data[], int len) { 175 int res; 176 int i; 177 178 if (cfg->is_ip232) { 179 res = ip232_read(cfg, data, len); 180 } else { 181 res = ser_read(cfg->ifd, data, len); 182 } 183 if(0 < res) { 184 LOG(LOG_DEBUG, "Read %d bytes from serial port", res); 185 if(0 < cfg->parity) { 186 for (i = 0; i < res; i++) { 187 data[i] &= 0x7f; // strip parity from returned data 188 } 189 } 190 log_trace(TRACE_SERIAL_IN, data, res); 191 } 192 return res; 193 } 194 195 int dce_read_char_raw(dce_config *cfg) { 196 int res; 197 unsigned char data[1]; 198 199 if (cfg->is_ip232) { 200 res = ip232_read(cfg, data, 1); 201 } else { 202 res = ser_read(cfg->ifd, data, 1); 203 } 204 if(0 < res) { 205 res = data[0]; 206 LOG(LOG_DEBUG, "Read 1 raw byte from serial port"); 207 log_trace(TRACE_SERIAL_IN, data, 1); 208 } 209 return res; 210 } 211 212 void dce_detect_parity(dce_config *cfg, unsigned char a, unsigned char t) { 213 cfg->parity = detect_parity(a, t); 214 } 215 216 int dce_strip_parity(dce_config *cfg, unsigned char data) { 217 return (cfg->parity ? data & 0x7f : data); 218 } 219 220 int dce_get_parity(dce_config *cfg) { 221 return cfg->parity; 222 } 223