#include #include #include #include #include "debug.h" #include "serial.h" #include "modem_core.h" #include "ip232.h" // needs modem_core.h #include "dce.h" void dce_init_config(dce_config *cfg) { cfg->parity = -1; // parity not yet checked. } int detect_parity (int charA, int charT) { int parity, eobits; parity = ((charA >> 6) & 2) | (charT >> 7); eobits = gen_parity(charA & 0x7f) << 1 | gen_parity(charT & 0x7f); if((parity == 1) || (parity == 2)) { if(parity == eobits) return PARITY_EVEN; else return PARITY_ODD; } else return parity; } int dce_connect(dce_config *cfg) { int rc; LOG_ENTER(); if (cfg->is_ip232) { rc = ip232_init_conn(cfg); } else { rc = ser_init_conn(cfg->tty, cfg->port_speed); if(-1 < rc) { cfg->is_connected = TRUE; cfg->ofd = rc; cfg->ifd = rc; } } LOG_EXIT(); return rc; } int dce_set_flow_control(dce_config *cfg, int opts) { int status = 0; int rc = 0; LOG_ENTER(); if(opts == 0) { LOG(LOG_ALL, "Setting NONE flow control"); } else { if((opts & MDM_FC_RTS) != 0) { LOG(LOG_ALL, "Setting RTSCTS flow control"); status |= CRTSCTS; } if((opts & MDM_FC_XON) != 0) { status |= (IXON | IXOFF); LOG(LOG_ALL, "Setting XON/XOFF flow control"); } } if (cfg->is_ip232) { rc = ip232_set_flow_control(cfg, status); } else { rc = ser_set_flow_control(cfg->ofd, status); } LOG_EXIT() return rc; } int dce_set_control_lines(dce_config *cfg, int state) { int rc; LOG_ENTER(); // if((state & DCE_CL_CTS) != 0) { // LOG(LOG_ALL, "Setting CTS pin high"); // } else { // LOG(LOG_ALL, "Setting CTS pin low"); // } if((state & DCE_CL_DCD) != 0) { LOG(LOG_ALL, "Setting DCD pin high"); } else { LOG(LOG_ALL, "Setting DCD pin low"); } if((state & DCE_CL_RI) != 0) { LOG(LOG_ALL, "Setting RI pin high"); } else { LOG(LOG_ALL, "Setting RI pin low"); } if (cfg->is_ip232) { rc = ip232_set_control_lines(cfg, state); } else { rc = ser_set_control_lines(cfg->ofd, state); } LOG_EXIT(); return rc; } int dce_get_control_lines(dce_config *cfg) { int state; if (cfg->is_ip232) { state = ip232_get_control_lines(cfg); } else { state = ser_get_control_lines(cfg->ifd); } return state; } int dce_check_control_lines(dce_config *cfg) { int state = 0; int new_state = 0; LOG_ENTER(); state = dce_get_control_lines(cfg); new_state = state; while(new_state > -1 && state == new_state) { usleep(100000); new_state = dce_get_control_lines(cfg); } LOG_EXIT(); return new_state; } int dce_write(dce_config *cfg, unsigned char data[], int len) { unsigned char *buf; int rc; int i; log_trace(TRACE_SERIAL_OUT, data, len); if (cfg->is_ip232) { return ip232_write(cfg, data, len); } else if(cfg->parity) { buf = malloc(len); // TODO what if malloc fails? memcpy(buf, data, len); if(0 < cfg->parity) { for (i = 0; i < len; i++) { buf[i] = apply_parity(data[i], cfg->parity); } } } else { buf = data; } rc = ser_write(cfg->ofd, buf, len); if(cfg->parity) free(buf); return rc; } int dce_write_char_raw(dce_config *cfg, unsigned char data) { int rc; log_trace(TRACE_SERIAL_OUT, &data, 1); if (cfg->is_ip232) { rc = ip232_write(cfg, &data, 1); } else { rc = ser_write(cfg->ofd, &data, 1); } return rc; } int dce_read(dce_config *cfg, unsigned char data[], int len) { int res; int i; if (cfg->is_ip232) { res = ip232_read(cfg, data, len); } else { res = ser_read(cfg->ifd, data, len); } if(0 < res) { LOG(LOG_DEBUG, "Read %d bytes from serial port", res); if(0 < cfg->parity) { for (i = 0; i < res; i++) { data[i] &= 0x7f; // strip parity from returned data } } log_trace(TRACE_SERIAL_IN, data, res); } return res; } int dce_read_char_raw(dce_config *cfg) { int res; unsigned char data[1]; if (cfg->is_ip232) { res = ip232_read(cfg, data, 1); } else { res = ser_read(cfg->ifd, data, 1); } if(0 < res) { res = data[0]; LOG(LOG_DEBUG, "Read 1 raw byte from serial port"); log_trace(TRACE_SERIAL_IN, data, 1); } return res; } void dce_detect_parity(dce_config *cfg, unsigned char a, unsigned char t) { cfg->parity = detect_parity(a, t); } int dce_strip_parity(dce_config *cfg, unsigned char data) { return (cfg->parity ? data & 0x7f : data); } int dce_get_parity(dce_config *cfg) { return cfg->parity; }