Re: Telnet command question
For my send, I just use the Send member of the AsyncSocket class. For now, I
just check Ethereal to see that all data transmitted from the client app (and
it does).
Here's my state "machine" function:
BOOL IRCamera::TelnetInit()
{
unsigned char buff[100], current_byte = 0;
//telnet states
//1 - starting state
//2 - received IAC, command to follow
//3 - received DO command, waiting for option
//4 - received Terminal, send back will negotiate terminal
//5 - received SB, waiting for option
//6 - received terminal, waiting for parameter
//7 - received send terminal type, return to state 1
//8 - received SB-end, send back terminal type ANSI
//9 - received WILL, waiting for option
//10 - received 01 (echo), send back don't echo
//11 - received 03 suppress, send back nothing
//12 - received WONT, wait for option
//13 - received 01 (echo), done
//14 - received 01 (echo), done
while(m_strRecvBuff.GetLength() > 0){
memset(buff, 0, sizeof(buff));
current_byte = m_strRecvBuff[0];
switch(current_byte){
case 0xff: // IAC - telnet commands to follow
m_strRecvBuff.Delete(0,1);
telnet_state = 2;
break;
case 0xfd: // DO command
m_strRecvBuff.Delete(0,1);
telnet_state = 3;
break;
case 0x18: // terminal type
m_strRecvBuff.Delete(0,1);
if(telnet_state == 3){
//when received IAC-DO-Terminal type, send back IAC WILL Terminal type
telnet_state = 1;
buff[0] = 0xff; // IAC
buff[1] = 0xfb; // WILL
buff[2] = 0x18; // Terminal type
pAsyncClient->Send(buff, 3, 0);
}
else if(telnet_state == 5){
telnet_state = 6; // waiting for parameter
}
break;
case 0xfa: // Sub Option
m_strRecvBuff.Delete(0,1);
telnet_state = 5;
break;
case 0x01: // Send terminal type or ECHO
m_strRecvBuff.Delete(0,1);
if(telnet_state == 6)
telnet_state = 1; //waiting for sub option end
else if(telnet_state == 12){
current_state = 1; //received wont echo
}
else if(telnet_state == 9){
//state 10
buff[0] = 0xff; // IAC
buff[1] = 0xfe; // DONT
buff[2] = 0x01; // echo
pAsyncClient->Send(buff, 3, 0);
telnet_state = 1;
}
else{
//state 14
buff[0] = 0xff; // IAC
buff[1] = 0xfc; // WONT
buff[2] = 0x01; // echo
pAsyncClient->Send(buff, 3, 0);
telnet_state = 1;
}
break;
case 0xf0: // SB (sub-option) end
//state 8
m_strRecvBuff.Delete(0,1);
telnet_state = 1;
buff[0] = 0xff; // IAC
buff[1] = 0xfa; // SB
buff[2] = 0x18; // terminal type
buff[3] = 0x00; // here's my terminal type
buff[4] = 0x41; // 'A'
buff[5] = 0x4e; // 'N'
buff[6] = 0x53; // 'S'
buff[7] = 0x49; // 'I'
buff[8] = 0xff; // IAC
buff[9] = 0xf0; // SB end
pAsyncClient->Send(buff, 10,0);
break;
case 0xfb: // WILL
//state 9
m_strRecvBuff.Delete(0,1);
telnet_state = 9;
break;
case 0xfc: //WONT
//state 12
m_strRecvBuff.Delete(0,1);
telnet_state = 12;
break;
case 0x03: // Suppress Go ahead
//state 11
m_strRecvBuff.Delete(0,1);
telnet_state = 1;
buff[0] = 0xff; // IAC
buff[1] = 0xfd; // DO
buff[2] = 0x03; // Suppress Go ahead
pAsyncClient->Send(buff, 3, 0);
break;
case 0xfe: // DONT
m_strRecvBuff.Delete(0,1);
break;
default:
m_strRecvBuff.Delete(0,1);
break;
}
}
return 0;
}
And when I send, an example follows:
//off denotes lenscover "off" or open, on denotes lenscover "on" or closed
int IRCamera::LensCover(int status){
CString temp = "lenscover ";
if(status)
temp += "on\r";
else
temp += "off\r";
return pAsyncClient->Send(temp, temp.GetLength(),0);
}
If I send a command after everything settles down, it responds back. What
gives? Thanks.
Vinoj
"Norbert Unterberg" wrote:
Vinoj schrieb:
Also, I'm using Ethereal to see what data is actually being transferred and
if I step through it responds with all the correct data. If I run at normal
speed, it looks like it chokes. Starts to echo back and stops.
How do you send, can you show some code?
Does the send function succeed or does it return an error?
If Send fails and GetLastError returns WSAWOULDBLOCK, that would
indicate that you are not using the socket correctly. When calling Send
more than once, you must make sure that either the socket is set to
blocking mode or check if Send is allowed (by sending only after the
OnSend() notification.
Do you split your send in multiple send calls, or do you send one
command at a time?
Norbert
[long quotes deleted]