Always strip/add parity if it is detected.
This commit is contained in:
parent
4b3dcc20d0
commit
04e0abc7f7
13
README.md
13
README.md
@ -1,4 +1,5 @@
|
||||
This is yet another fork of Jim Brain's tcpser serial to IP modem emulation program.
|
||||
|
||||
The original source code can be found here:
|
||||
http://www.jbrain.com/pub/linux/serial/
|
||||
|
||||
@ -6,12 +7,12 @@ My changes are based upon the rc12 archive dated 11Mar09.
|
||||
|
||||
I fixed the bug with being unable to connect to real telnet servers.
|
||||
|
||||
I also made the modem routines automatically detect parity and ignore
|
||||
it in AT commands and print out modem responses in matching
|
||||
parity. Parity is *not* stripped when sending data over the
|
||||
connection, which is how a real modem behaves. This may or may not be
|
||||
what you want. Some servers will expect an 8 bit connection and may
|
||||
not work.
|
||||
I also made the modem routines automatically detect parity. If even,
|
||||
odd, or mark parity is detected then the telnet connection will be
|
||||
limited to 7 bit. Space parity will be treated as 8N1 and will allow
|
||||
telnet binary mode.
|
||||
|
||||
I also incorporated geneb's changes found at https://github.com/geneb/tcpser
|
||||
|
||||
Chris Osborn <fozztexx@fozztexx.com>
|
||||
http://insentricity.com
|
||||
|
@ -385,7 +385,6 @@ void *run_bridge(void *arg)
|
||||
}
|
||||
else
|
||||
mdm_send_ring(cfg);
|
||||
|
||||
}
|
||||
else
|
||||
mdm_handle_timeout(cfg);
|
||||
|
10
src/line.c
10
src/line.c
@ -22,9 +22,13 @@ int line_write(modem_config *cfg, char *data, int len)
|
||||
int double_iac = FALSE;
|
||||
char text[1024];
|
||||
int text_len = 0;
|
||||
int mask = 0x7f;
|
||||
|
||||
|
||||
if (cfg->line_data.is_telnet && cfg->line_data.nvt_data.binary_xmit) {
|
||||
if (cfg->line_data.is_telnet) {
|
||||
if (cfg->line_data.nvt_data.binary_xmit)
|
||||
mask = 0xff;
|
||||
|
||||
retval = 0;
|
||||
while (i < len) {
|
||||
if (double_iac) {
|
||||
@ -38,10 +42,10 @@ int line_write(modem_config *cfg, char *data, int len)
|
||||
double_iac = TRUE;
|
||||
}
|
||||
else {
|
||||
text[text_len++] = data[i++];
|
||||
text[text_len++] = data[i++] & mask;
|
||||
}
|
||||
}
|
||||
if (text_len == 1024) {
|
||||
if (text_len == sizeof(text_len)) {
|
||||
retval = ip_write(cfg->line_data.fd, text, text_len);
|
||||
text_len = 0;
|
||||
}
|
||||
|
@ -178,14 +178,7 @@ void mdm_write_char(modem_config *cfg, char data)
|
||||
mdm_write(cfg, str, 1);
|
||||
}
|
||||
|
||||
void mdm_write(modem_config *cfg, char data[], int len)
|
||||
{
|
||||
if (cfg->allow_transmit == TRUE) {
|
||||
dce_write(cfg, data, len);
|
||||
}
|
||||
}
|
||||
|
||||
void mdm_write_parity(modem_config *cfg, char *data, int len)
|
||||
void mdm_write(modem_config *cfg, char *data, int len)
|
||||
{
|
||||
unsigned char *buf;
|
||||
int i;
|
||||
@ -193,18 +186,23 @@ void mdm_write_parity(modem_config *cfg, char *data, int len)
|
||||
|
||||
|
||||
if (cfg->allow_transmit == TRUE) {
|
||||
if (cfg->parity) {
|
||||
buf = malloc(len);
|
||||
memcpy(buf, data, len);
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
v = buf[i];
|
||||
v = (((v * 0x0101010101010101ULL) & 0x8040201008040201ULL) % 0x1FF) & 1;
|
||||
buf[i] &= 0x7f;
|
||||
buf[i] |= (((cfg->parity >> !v)) & 1) << 7;
|
||||
}
|
||||
|
||||
mdm_write(cfg, (char *) buf, len);
|
||||
dce_write(cfg, (char *) buf, len);
|
||||
free(buf);
|
||||
}
|
||||
else
|
||||
dce_write(cfg, data, len);
|
||||
}
|
||||
}
|
||||
|
||||
void mdm_send_response(int msg, modem_config *cfg)
|
||||
@ -214,17 +212,17 @@ void mdm_send_response(int msg, modem_config *cfg)
|
||||
|
||||
LOG(LOG_DEBUG, "Sending %s response to modem", mdm_responses[msg]);
|
||||
if (cfg->send_responses == TRUE) {
|
||||
mdm_write_parity(cfg, cfg->crlf, 2);
|
||||
mdm_write(cfg, cfg->crlf, 2);
|
||||
if (cfg->text_responses == TRUE) {
|
||||
LOG(LOG_ALL, "Sending text response");
|
||||
mdm_write_parity(cfg, mdm_responses[msg], strlen(mdm_responses[msg]));
|
||||
mdm_write(cfg, mdm_responses[msg], strlen(mdm_responses[msg]));
|
||||
}
|
||||
else {
|
||||
LOG(LOG_ALL, "Sending numeric response");
|
||||
sprintf(msgID, "%d", msg);
|
||||
mdm_write_parity(cfg, msgID, strlen(msgID));
|
||||
mdm_write(cfg, msgID, strlen(msgID));
|
||||
}
|
||||
mdm_write_parity(cfg, cfg->crlf, 2);
|
||||
mdm_write(cfg, cfg->crlf, 2);
|
||||
}
|
||||
}
|
||||
|
||||
@ -389,8 +387,8 @@ int mdm_parse_cmd(modem_config *cfg)
|
||||
strncpy(cfg->dialno, cfg->last_dialno, strlen(cfg->last_dialno));
|
||||
cfg->dial_type = cfg->dial_type;
|
||||
cfg->memory_dial = TRUE;
|
||||
mdm_write_parity(cfg, cfg->crlf, 2);
|
||||
mdm_write_parity(cfg, cfg->dialno, strlen(cfg->dialno));
|
||||
mdm_write(cfg, cfg->crlf, 2);
|
||||
mdm_write(cfg, cfg->dialno, strlen(cfg->dialno));
|
||||
}
|
||||
else {
|
||||
cfg->dialno[0] = 0;
|
||||
@ -477,7 +475,7 @@ int mdm_parse_cmd(modem_config *cfg)
|
||||
break;
|
||||
case AT_CMD_FLAG_QUERY | 'S':
|
||||
sprintf(tmp, "%s%3.3d", cfg->crlf, cfg->s[num]);
|
||||
mdm_write_parity(cfg, tmp, strlen(tmp));
|
||||
mdm_write(cfg, tmp, strlen(tmp));
|
||||
break;
|
||||
case 'T': // defaut to tone dialing
|
||||
//cfg->default_dial_type=MDM_DT_TONE;
|
||||
@ -576,7 +574,7 @@ int mdm_handle_char(modem_config *cfg, char ch)
|
||||
if (cfg->cmd_started == TRUE) {
|
||||
if (ch == (char) (cfg->s[5])) {
|
||||
if (cfg->cur_line_idx == 0 && cfg->echo == TRUE) {
|
||||
mdm_write_parity(cfg, "T", 1);
|
||||
mdm_write(cfg, "T", 1);
|
||||
}
|
||||
else {
|
||||
cfg->cur_line_idx--;
|
||||
@ -631,6 +629,7 @@ int mdm_clear_break(modem_config *cfg)
|
||||
int mdm_parse_data(modem_config *cfg, char *data, int len)
|
||||
{
|
||||
int i;
|
||||
int ch;
|
||||
|
||||
|
||||
if (cfg->cmd_mode == TRUE) {
|
||||
@ -642,7 +641,10 @@ int mdm_parse_data(modem_config *cfg, char *data, int len)
|
||||
line_write(cfg, data, len);
|
||||
if (cfg->pre_break_delay == TRUE) {
|
||||
for (i = 0; i < len; i++) {
|
||||
if (data[i] == (char) cfg->s[2]) {
|
||||
ch = data[i];
|
||||
if (cfg->parity)
|
||||
ch &= 0x7f;
|
||||
if (ch == (char) cfg->s[2]) {
|
||||
LOG(LOG_DEBUG, "Break character received");
|
||||
cfg->break_len++;
|
||||
if (cfg->break_len > 3) { // more than 3, considered invalid
|
||||
|
Loading…
x
Reference in New Issue
Block a user