ctk-termtelnet.c
来自「伟大的Contiki工程, 短小精悍 的操作系统, 学习编程不可不看」· C语言 代码 · 共 656 行 · 第 1/2 页
C
656 行
tns->tnsm.myOpt[opt].state = TNOS_YES; Reply(tns, TN_WILL, opt); } else { Reply(tns, TN_WONT, opt); } break; case TNOS_WANTNO_EMPTY: tns->tnsm.myOpt[opt].state = TNOS_NO; break; case TNOS_WANTNO_OPPOSITE: tns->tnsm.myOpt[opt].state = TNOS_YES; break; case TNOS_WANTYES_EMPTY: tns->tnsm.myOpt[opt].state = TNOS_YES; break; case TNOS_WANTYES_OPPOSITE: tns->tnsm.myOpt[opt].state = TNOS_WANTNO_EMPTY; Reply(tns, TN_WONT, opt); break; case TNOS_YES: break; } break; case TN_DONT: switch(tns->tnsm.myOpt[opt].state) { case TNOS_NO: break; case TNOS_WANTNO_EMPTY: case TNOS_WANTYES_EMPTY: case TNOS_WANTYES_OPPOSITE: tns->tnsm.myOpt[opt].state = TNOS_NO; break; case TNOS_WANTNO_OPPOSITE: tns->tnsm.myOpt[opt].state = TNOS_WANTYES_EMPTY; Reply(tns, TN_WILL, opt); break; case TNOS_YES: tns->tnsm.myOpt[opt].state = TNOS_NO; Reply(tns, TN_WONT, opt); break; } break; } } else { switch(cmd) { case TN_WILL: Reply(tns, TN_DONT, opt); break; case TN_WONT: break; case TN_DO: Reply(tns, TN_WONT, opt); break; case TN_DONT: break; } }}/*-----------------------------------------------------------------------------------*//* * Telnet data parsing *//*-----------------------------------------------------------------------------------*/static unsigned charparse_input(struct telnet_state* tns, unsigned char b){ unsigned char ret = 0; switch(tns->tnsm.state) { case TNS_IDLE: if (b == TN_IAC) tns->tnsm.state = TNS_IAC; else ret = 1; break; case TNS_IAC: switch(b) { case TN_SE: case TN_NOP: case TN_DM: case TN_BRK: case TN_IP: case TN_AO: case TN_AYT: case TN_EC: case TN_EL: case TN_GA: tns->tnsm.state = TNS_IDLE; break; case TN_SB: tns->tnsm.state = TNS_SB; break; case TN_WILL: case TN_WONT: case TN_DO: case TN_DONT: tns->tnsm.cmd = b; tns->tnsm.state = TNS_OPT; break; case TN_IAC: tns->tnsm.state = TNS_IDLE; ret = 1; break; default: /* Drop unknown IACs */ tns->tnsm.state = TNS_IDLE; break; } break; case TNS_OPT: HandleCommand(tns, tns->tnsm.cmd, b); tns->tnsm.state = TNS_IDLE; break; case TNS_SB: if (b == TN_IAC) { tns->tnsm.state = TNS_SBIAC; } break; case TNS_SBIAC: if (b == TN_IAC) { tns->tnsm.state = TNS_SB; } else if (b == TN_SE) { tns->tnsm.state = TNS_IDLE; } else { tns->tnsm.state = TNS_IDLE; } break; } return ret;}/*-----------------------------------------------------------------------------------*//* * Initialize telnet machine *//*-----------------------------------------------------------------------------------*/static voidtelnet_init(struct telnet_state* tns){ int i; for (i = 0; i < TNSM_MAX_OPTIONS; i++) { tns->tnsm.myOpt[i].state = TNOS_NO; tns->tnsm.myOpt[i].wants = 0; tns->tnsm.hisOpt[i].state = TNOS_NO; tns->tnsm.hisOpt[i].wants = 0; } tns->tnsm.state = TNS_IDLE;}/*-----------------------------------------------------------------------------------*//* * Allocate a telnet session structure (including terminal state) *//*-----------------------------------------------------------------------------------*/static struct telnet_state*alloc_state(){ for (i=0; i < NUM_CONNS; i++) { if (states[i].state == TTS_FREE) { states[i].termstate = ctk_term_alloc_state(); if (states[i].termstate != NULL) { for (j = 0; j < TNQLEN; j++) { states[i].sendq[j] = 0; } telnet_init(&states[i]); states[i].state = TTS_IDLE; return &(states[i]); } } } return NULL;}/*-----------------------------------------------------------------------------------*//* * Free a telnet session structure (including terminal state) *//*-----------------------------------------------------------------------------------*/static voidfree_state(struct telnet_state* tns){ if (tns != NULL) { ctk_term_dealloc_state(tns->termstate); tns->state = TTS_FREE; }}/*-----------------------------------------------------------------------------------*//* * A packet is successfully sent *//*-----------------------------------------------------------------------------------*/static voidacked(struct telnet_state* tns){ /* Were we sending a telnet option packet? */ if (tns->state == TTS_SEND_TNDATA) { /* Yes, free it and update queue */ if (tns->sendq[0] != 0) { memb_free(&telnetbuf, (char*)(tns->sendq[0])); for (i=1; i < TNQLEN; i++) { tns->sendq[i-1] = tns->sendq[i]; } tns->sendq[TNQLEN-1] = 0; /* No options left. Go idle */ if (tns->sendq[0] == 0) { tns->state = TTS_IDLE; } } } /* Or were we sending application date ? */ else if (tns->state == TTS_SEND_APPDATA) { /* Inform application that data is sent successfully */ ctk_term_sent(tns->termstate); tns->state = TTS_IDLE; }}/*-----------------------------------------------------------------------------------*//* * Send data on a connections *//*-----------------------------------------------------------------------------------*/static voidsenddata(struct telnet_state* tns){ /* Check if there are any option packets to send */ if (tns->state == TTS_IDLE || tns->state == TTS_SEND_TNDATA) { if (tns->sendq[0] != 0) { tns->state = TTS_SEND_TNDATA; uip_send(tns->sendq[0],3); } } /* Check if terminal wants to send any data */ if (tns->state == TTS_IDLE || tns->state == TTS_SEND_APPDATA) { u16_t len = ctk_term_send(tns->termstate, (unsigned char*)uip_appdata, (unsigned short)uip_mss()); if (len > 0) { tns->state = TTS_SEND_APPDATA; uip_send(uip_appdata, len); } }}/*-----------------------------------------------------------------------------------*//* * uIP callback *//*-----------------------------------------------------------------------------------*/static voidctk_termtelnet_appcall(void *state){ struct telnet_state *tns; tns = (struct telnet_state*)(state); if(uip_connected()) { if(tns == NULL) { tns = alloc_state(); if(tns == NULL) { uip_close(); return; } tcp_markconn(uip_conn, (void *)tns); } /* Try to negotiate some options */ EnableHisOpt(tns, TNO_SGA); EnableMyOpt(tns,TNO_SGA); EnableMyOpt(tns,TNO_ECHO); /* Request update of screen */ ctk_term_redraw(tns->termstate); senddata(tns); } else if(uip_closed() || uip_aborted()) { free_state(tns); return; } if (uip_acked()) { acked(tns); } if (uip_newdata()) { for(j = 0; j < uip_datalen(); j++) { if (parse_input(tns, uip_appdata[j])) { /* Pass it uppwards */ ctk_term_input(tns->termstate, uip_appdata[j]); } } } if(uip_rexmit() || uip_newdata() || uip_acked()) { senddata(tns); } else if(uip_poll()) { if (tns->state == TTS_IDLE) { senddata(tns); } }}/*-----------------------------------------------------------------------------------*//* * Init function *//*-----------------------------------------------------------------------------------*/LOADER_INIT_FUNC(ctk_termtelnet_init, arg){ arg_free(arg); if(id == EK_ID_NONE) { memb_init(&telnetbuf); for (i=0; i < NUM_CONNS; i++) { states[i].state = TTS_FREE; } id = ek_start(&p); }}/*-----------------------------------------------------------------------------------*/EK_EVENTHANDLER(eventhandler, ev, data){ if(ev == EK_EVENT_INIT) { tcp_listen(HTONS(PORT)); } else if(ev == tcpip_event) { ctk_termtelnet_appcall(data); }}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?