📄 softmodem.cpp
字号:
EnterIdleState(); return; } //Else return ok };break; case 'O': //Return to data mode switch (num=ScanNumber(scanbuf)) { case 0: if (clientsocket) { commandmode = false; return; } else { SendRes(ResERROR); return; } };break; case 'T': //Tone Dial case 'P': //Pulse Dial break; case 'M': //Monitor case 'L': //Volume ScanNumber(scanbuf); break; case 'A': //Answer call if (waitingclientsocket) { AcceptIncomingCall(); } else { SendRes(ResERROR); return; } return; case 'Z': //Reset and load profiles { // scan the number away, if any ScanNumber(scanbuf); if (clientsocket/*socket*/) SendRes(ResNOCARRIER); Reset(); break; } case ' ': //Space just skip break; case 'Q': // Response options { // 0 = all on, 1 = all off, // 2 = no ring and no connect/carrier in answermode Bitu val = ScanNumber(scanbuf); if(!(val>2)) { doresponse=val; break; } else { SendRes(ResERROR); return; } } case 'S': //Registers { Bitu index=ScanNumber(scanbuf); if(index>=SREGS) { SendRes(ResERROR); return; //goto ret_none; } while(scanbuf[0]==' ') scanbuf++; // skip spaces if(scanbuf[0]=='=') { // set register scanbuf++; while(scanbuf[0]==' ') scanbuf++; // skip spaces Bitu val = ScanNumber(scanbuf); reg[index]=val; break; } else if(scanbuf[0]=='?') { // get register SendNumber(reg[index]); scanbuf++; break; } //else LOG_MSG("print reg %d with %d",index,reg[index]); } break; case '&': { if(scanbuf[0]!=0) { char ch = scanbuf[0]; scanbuf++; switch(ch) { case 'K': { Bitu val = ScanNumber(scanbuf); if(val<5) flowcontrol=val; else { SendRes(ResERROR); return; } break; } default: { scanbuf++; LOG_MSG("Modem: Unhandled command: &%c%d",ch,ScanNumber(scanbuf)); break; } } } else { SendRes(ResERROR); return; } } break; default: LOG_MSG("Modem: Unhandled command: %c%d",chr,ScanNumber(scanbuf)); } } SendRes(ResOK); return; }void CSerialModem::TelnetEmulation(Bit8u * data, Bitu size) { Bitu i; Bit8u c; for(i=0;i<size;i++) { c = data[i]; if(telClient.inIAC) { if(telClient.recCommand) { if((c != 0) && (c != 1) && (c != 3)) { LOG_MSG("MODEM: Unrecognized option %d", c); if(telClient.command>250) { /* Reject anything we don't recognize */ tqueue->addb(0xff); tqueue->addb(252); tqueue->addb(c); /* We won't do crap! */ } } switch(telClient.command) { case 251: /* Will */ if(c == 0) telClient.binary[TEL_SERVER] = true; if(c == 1) telClient.echo[TEL_SERVER] = true; if(c == 3) telClient.supressGA[TEL_SERVER] = true; break; case 252: /* Won't */ if(c == 0) telClient.binary[TEL_SERVER] = false; if(c == 1) telClient.echo[TEL_SERVER] = false; if(c == 3) telClient.supressGA[TEL_SERVER] = false; break; case 253: /* Do */ if(c == 0) { telClient.binary[TEL_CLIENT] = true; tqueue->addb(0xff); tqueue->addb(251); tqueue->addb(0); /* Will do binary transfer */ } if(c == 1) { telClient.echo[TEL_CLIENT] = false; tqueue->addb(0xff); tqueue->addb(252); tqueue->addb(1); /* Won't echo (too lazy) */ } if(c == 3) { telClient.supressGA[TEL_CLIENT] = true; tqueue->addb(0xff); tqueue->addb(251); tqueue->addb(3); /* Will Suppress GA */ } break; case 254: /* Don't */ if(c == 0) { telClient.binary[TEL_CLIENT] = false; tqueue->addb(0xff); tqueue->addb(252); tqueue->addb(0); /* Won't do binary transfer */ } if(c == 1) { telClient.echo[TEL_CLIENT] = false; tqueue->addb(0xff); tqueue->addb(252); tqueue->addb(1); /* Won't echo (fine by me) */ } if(c == 3) { telClient.supressGA[TEL_CLIENT] = true; tqueue->addb(0xff); tqueue->addb(251); tqueue->addb(3); /* Will Suppress GA (too lazy) */ } break; default: LOG_MSG("MODEM: Telnet client sent IAC %d", telClient.command); break; } telClient.inIAC = false; telClient.recCommand = false; continue; } else { if(c==249) { /* Go Ahead received */ telClient.inIAC = false; continue; } telClient.command = c; telClient.recCommand = true; if((telClient.binary[TEL_SERVER]) && (c == 0xff)) { /* Binary data with value of 255 */ telClient.inIAC = false; telClient.recCommand = false; rqueue->addb(0xff); continue; } } } else { if(c == 0xff) { telClient.inIAC = true; continue; } rqueue->addb(c); } }}void CSerialModem::Timer2(void) { unsigned long args = 1; bool sendbyte = true; Bitu usesize; Bit8u txval; Bitu txbuffersize =0; // check for bytes to be sent to port if(CSerial::CanReceiveByte()) if(rqueue->inuse() && (CSerial::getRTS()||(flowcontrol!=3))) { Bit8u rbyte = rqueue->getb(); //LOG_MSG("Modem: sending byte %2x back to UART3",rbyte); CSerial::receiveByte(rbyte); } // Check for eventual break command if (!commandmode) cmdpause++; // Handle incoming data from serial port, read as much as available CSerial::setCTS(true); // buffer will get 'emptier', new data can be received while (tqueue->inuse()) { txval = tqueue->getb(); if (commandmode) { if (echo) { rqueue->addb(txval); //LOG_MSG("Echo back to queue: %x",txval); } if (txval==0xa) continue; //Real modem doesn't seem to skip this? else if (txval==0x8 && (cmdpos > 0)) --cmdpos; // backspace else if (txval==0xd) DoCommand(); // return else if (txval != '+') { if(cmdpos<99) { cmdbuf[cmdpos] = txval; cmdpos++; } } } else {// + character // 1000 ticks have passed, can check for pause command if (cmdpause > 1000) { if(txval ==reg[MREG_ESCAPE_CHAR]) // + { plusinc++; if(plusinc>=3) { LOG_MSG("Modem: Entering command mode(escape sequence)"); commandmode = true; SendRes(ResOK); plusinc = 0; } sendbyte=false; } else { plusinc=0; } // If not a special pause command, should go for bigger blocks to send } tmpbuf[txbuffersize] = txval; txbuffersize++; } } // while loop if (clientsocket && sendbyte && txbuffersize) { // down here it saves a lot of network traffic clientsocket->SendArray(tmpbuf,txbuffersize); //TODO error testing } // Handle incoming to the serial port if(!commandmode && clientsocket && rqueue->left()) { usesize = rqueue->left(); if (usesize>16) usesize=16; if(!clientsocket->ReceiveArray(tmpbuf, &usesize)) { SendRes(ResNOCARRIER); EnterIdleState(); } else if(usesize) { // LOG_MSG("rcv:%d", result); // Filter telnet commands if(telnetmode) TelnetEmulation(tmpbuf, usesize); else rqueue->adds(tmpbuf,usesize); cmdpause = 0; } } // Check for incoming calls if (!connected && !waitingclientsocket && serversocket) { waitingclientsocket=serversocket->Accept(); if(waitingclientsocket) { if(!CSerial::getDTR()) { // accept no calls with DTR off; TODO: AT &Dn EnterIdleState(); } else { ringing=true; SendRes(ResRING); CSerial::setRI(!CSerial::getRI()); //MIXER_Enable(mhd.chan,true); ringtimer = 3000; reg[1] = 0; //Reset ring counter reg } } } if (ringing) { if (ringtimer <= 0) { reg[1]++; if ((reg[0]>0) && (reg[0]>=reg[1])) { AcceptIncomingCall(); return; } SendRes(ResRING); CSerial::setRI(!CSerial::getRI()); //MIXER_Enable(mhd.chan,true); ringtimer = 3000; } --ringtimer; }}//TODOvoid CSerialModem::RXBufferEmpty() { // see if rqueue has some more bytes if(rqueue->inuse() && (CSerial::getRTS()||(flowcontrol!=3))){ Bit8u rbyte = rqueue->getb(); //LOG_MSG("Modem: sending byte %2x back to UART1",rbyte); CSerial::receiveByte(rbyte); }}void CSerialModem::transmitByte(Bit8u val, bool first) { waiting_tx_character=val; setEvent(MODEM_TX_EVENT, bytetime); // TX event if(first) ByteTransmitting(); //LOG_MSG("MODEM: Byte %x to be transmitted",val);}void CSerialModem::updatePortConfig(Bit16u, Bit8u lcr) { // nothing to do here right?}void CSerialModem::updateMSR() { // think it is not needed}void CSerialModem::setBreak(bool) { // TODO: handle this}void CSerialModem::setRTSDTR(bool rts, bool dtr) { setDTR(dtr);}void CSerialModem::setRTS(bool val) { }void CSerialModem::setDTR(bool val) { if(!val && connected) { // If DTR goes low, hang up. SendRes(ResNOCARRIER); EnterIdleState(); LOG_MSG("Modem: Hang up due to dropped DTR."); } }/*void CSerialModem::updateModemControlLines() { //bool txrdy=tqueue->left(); //if(CSerial::getRTS() && txrdy) CSerial::setCTS(true); //else CSerial::setCTS(tqueue->left()); // If DTR goes low, hang up. if(connected) if(oldDTRstate) if(!getDTR()) { SendRes(ResNOCARRIER); EnterIdleState(); LOG_MSG("Modem: Hang up due to dropped DTR."); } oldDTRstate = getDTR();}*/#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -