int modem_response(char *str, size_t maxlen, int timeout) { char ch; size_t len=0; time_t start; start=time(NULL); while(1){ /* Abort with keystroke */ if(kbhit()) { getch(); return(1); } if(time(NULL)-start >= timeout) return(-1); if(len >= maxlen) return(-1); if(!comReadByte(com, &ch)) { YIELD(); continue; } if(ch<' ' && len==0) /* ignore prepended control chars */ continue; if(ch=='\r') { // while(comReadByte(com,&ch)); /* eat trailing ctrl chars (e.g. 'LF') */ break; } str[len++]=ch; } str[len]=0; return(0); }
BOOL modem_response(COM_HANDLE com_handle, char *str, size_t maxlen) { BYTE ch; size_t len=0; time_t start; lprintf(LOG_DEBUG,"Waiting for Modem Response ..."); start=time(NULL); while(1){ if(time(NULL)-start >= mdm_timeout) { lprintf(LOG_WARNING,"Modem Response TIMEOUT (%lu seconds) on %s", mdm_timeout, com_dev); return FALSE; } if(len >= maxlen) { lprintf(LOG_WARNING,"Modem Response too long (%u >= %u) from %s" ,len, maxlen, com_dev); return FALSE; } if(!comReadByte(com_handle, &ch)) { YIELD(); continue; } if(ch<' ' && len==0) /* ignore prepended control chars */ continue; if(ch=='\r') { while(comReadByte(com_handle,&ch)) /* eat trailing ctrl chars (e.g. 'LF') */ #if 0 lprintf(LOG_DEBUG, "eating ch=%02X", ch) #endif ; break; } str[len++]=ch; } str[len]=0; return TRUE; }
void input_thread(void* arg) { BYTE ch; lprintf(LOG_DEBUG,"Input thread started"); while(!call_terminated) { if(!comReadByte(com_handle, &ch)) { YIELD(); continue; } if(telnet && ch==TELNET_IAC) sendsocket(sock, &ch, sizeof(ch)); /* escape Telnet IAC char (255) when in telnet mode */ sendsocket(sock, &ch, sizeof(ch)); bytes_received++; } lprintf(LOG_DEBUG,"Input thread terminated"); input_thread_terminated=TRUE; }
size_t COMIOCALL comReadBuf(COM_HANDLE handle, char* buf, size_t buflen, const char* terminators, int timeout) { BYTE ch; size_t len=0; msclock_t start=msclock(); while(len < buflen) { if(!comReadByte(handle, &ch)) { if(msclock()-start >= timeout) break; YIELD(); continue; } if(len && terminators!=NULL && strchr(terminators, ch)!=NULL) break; buf[len++]=ch; } return len; }
BOOL handle_call(void) { BYTE buf[4096]; BYTE telnet_buf[sizeof(buf)]; BYTE* p; int result; int rd; int wr; fd_set socket_set; struct timeval tv = {0, 0}; bytes_sent=0; bytes_received=0; call_terminated=FALSE; /* Reset Telnet state information */ telnet_cmdlen=0; ZERO_VAR(telnet_local_option); ZERO_VAR(telnet_remote_option); if(telnet && telnet_advertise_cid && (cid_number[0] || cid_name[0])) /* advertise the ability to send our location */ send_telnet_cmd(TELNET_WILL, TELNET_SEND_LOCATION); input_thread_terminated=FALSE; _beginthread(input_thread, 0, NULL); while(!terminated) { if(!dcd_ignore && !carrier_detect(com_handle)) { lprintf(LOG_WARNING,"Loss of Carrier Detect (DCD) detected"); break; } #if 0 /* single-threaded mode: */ if(comReadByte(com_handle, &ch)) { lprintf(LOG_DEBUG,"read byte: %c", ch); send(sock, &ch, sizeof(ch), 0); } #endif FD_ZERO(&socket_set); FD_SET(sock,&socket_set); if((result = select(sock+1,&socket_set,NULL,NULL,&tv)) == 0) { YIELD(); continue; } if(result == SOCKET_ERROR) { lprintf(LOG_ERR,"SOCKET ERROR %u on select", ERROR_VALUE); break; } rd=recv(sock,buf,sizeof(buf),0); if(rd < 1) { if(rd==0) { lprintf(LOG_WARNING,"Socket Disconnected"); break; } if(ERROR_VALUE == EAGAIN) continue; else if(ERROR_VALUE == ENOTSOCK) lprintf(LOG_WARNING,"Socket closed by peer on receive"); else if(ERROR_VALUE==ECONNRESET) lprintf(LOG_WARNING,"Connection reset by peer on receive"); else if(ERROR_VALUE==ESHUTDOWN) lprintf(LOG_WARNING,"Socket shutdown on receive"); else if(ERROR_VALUE==ECONNABORTED) lprintf(LOG_WARNING,"Connection aborted by peer on receive"); else lprintf(LOG_ERR,"SOCKET RECV ERROR %d",ERROR_VALUE); break; } if(telnet) p=telnet_interpret(buf,rd,telnet_buf,&rd); else p=buf; if((wr=comWriteBuf(com_handle, p, rd)) != COM_ERROR) bytes_sent += wr; } call_terminated=TRUE; /* terminate input_thread() */ while(!input_thread_terminated) { YIELD(); } lprintf(LOG_INFO,"Bytes sent-to, received-from COM Port: %lu, %lu" ,bytes_sent, bytes_received); return TRUE; }