U16 tnet_process_cmd (U8 *cmd, U8 *buf, U16 buflen, U32 *pvar) { /* This is a Telnet Client callback function to make a formatted output */ /* for 'stdout'. It returns the number of bytes written to the out buffer.*/ /* Hi-bit of return value (len is or-ed with 0x8000) is a disconnect flag.*/ /* Bit 14 (len is or-ed with 0x4000) is a repeat flag for the Tnet client.*/ /* If this bit is set to 1, the system will call the 'tnet_process_cmd()' */ /* again with parameter 'pvar' pointing to a 4-byte buffer. This buffer */ /* can be used for storing different status variables for this function. */ /* It is set to 0 by Telnet server on first call and is not altered by */ /* Telnet server for repeated calls. This function should NEVER write */ /* more than 'buflen' bytes to the buffer. */ /* Parameters: */ /* cmd - telnet received command string */ /* buf - Telnet transmit buffer */ /* buflen - length of this buffer (500-1400 bytes - depends on MSS) */ /* pvar - pointer to local storage buffer used for repeated loops */ /* This is a U32 variable - size is 4 bytes. Value is: */ /* - on 1st call = 0 */ /* - 2nd call = as set by this function on first call */ U16 len = 0; /* Simple Command line parser */ len = strlen ((const char *)cmd); if (tnet_ccmp (cmd, "RESET") == __TRUE) { /* 'RESET' command received */ sys_Reset(); return (len); } if (tnet_ccmp (cmd, "SPIF") == __TRUE) { extern int dbg_SpifInfo(uint8_t *pBuf); return dbg_SpifInfo(buf); } if (tnet_ccmp (cmd, "BYE") == __TRUE) { /* 'BYE' command, send message and disconnect */ len = str_copy (buf, "\r\nDisconnect...\r\n"); /* Hi bit of return value is a disconnect flag */ return (len | 0x8000); } if (tnet_ccmp (cmd, "TCPSTAT") == __TRUE) { /* Display a TCP status similar to that in HTTP_Demo example. */ /* Here the local storage '*pvar' is initialized to 0 by Telnet Server. */ MYBUF(pvar)->id = 1; len = str_copy (buf, CLS); return (len | 0x4000); } /* Unknown command, display message */ len = str_copy (buf, "\r\n==> Unknown Command: "); len += str_copy (buf+len, cmd); return (len); }
U16 cgi_func (U8 *env, U8 *buf, U16 buflen, U32 *pcgi) { /* This function is called by HTTP server script interpreter to make a */ /* formated output for 'stdout'. It returns the number of bytes written */ /* to the output buffer. Hi-bit of return value (len is or-ed with 0x8000)*/ /* is a repeat flag for the system script interpreter. If this bit is set */ /* to 1, the system will call the 'cgi_func()' again for the same script */ /* line with parameter 'pcgi' pointing to a 4-byte buffer. This buffer */ /* can be used for storing different status variables for this function. */ /* It is set to 0 by HTTP Server on first call and is not altered by */ /* HTTP server for repeated calls. This function should NEVER write more */ /* than 'buflen' bytes to the buffer. */ /* Parameters: */ /* env - environment variable string */ /* buf - HTTP transmit buffer */ /* buflen - length of this buffer (500-1400 bytes - depends on MSS) */ /* pcgi - pointer to session local buffer used for repeated loops */ /* This is a U32 variable - size is 4 bytes. Value is: */ /* - on 1st call = 0 */ /* - 2nd call = as set by this function on first call */ TCP_INFO *tsoc; U32 len = 0; U8 id, *lang; static U32 adv; switch (env[0]) { /* Analyze the environment string. It is the script 'c' line starting */ /* at position 2. What you write to the script file is returned here. */ case 'a' : /* Network parameters - file 'network.cgi' */ switch (env[2]) { case 'i': /* Write the local IP address. The format string is included */ /* in environment string of the script line. */ len = sprintf((char *)buf,(const char *)&env[4],LocM.IpAdr[0], LocM.IpAdr[1],LocM.IpAdr[2],LocM.IpAdr[3]); break; case 'm': /* Write local Net mask. */ len = sprintf((char *)buf,(const char *)&env[4],LocM.NetMask[0], LocM.NetMask[1],LocM.NetMask[2],LocM.NetMask[3]); break; case 'g': /* Write default gateway address. */ len = sprintf((char *)buf,(const char *)&env[4],LocM.DefGW[0], LocM.DefGW[1],LocM.DefGW[2],LocM.DefGW[3]); break; case 'p': /* Write primary DNS server address. */ len = sprintf((char *)buf,(const char *)&env[4],LocM.PriDNS[0], LocM.PriDNS[1],LocM.PriDNS[2],LocM.PriDNS[3]); break; case 's': /* Write secondary DNS server address. */ len = sprintf((char *)buf,(const char *)&env[4],LocM.SecDNS[0], LocM.SecDNS[1],LocM.SecDNS[2],LocM.SecDNS[3]); break; } break; case 'b': /* LED control - file 'led.cgi' */ if (env[2] == 'c') { /* Select Control */ len = sprintf((char *)buf,(const char *)&env[4],LEDrun ? "" : "selected", LEDrun ? "selected" : ""); break; } /* LED CheckBoxes */ id = env[2] - '0'; if (id > 7) { id = 0; } id = 1 << id; len = sprintf((char *)buf,(const char *)&env[4],(P2 & id) ? "checked" : ""); break; case 'c': /* TCP status - file 'tcp.cgi' */ while ((len + 150) < buflen) { tsoc = &tcp_socket[MYBUF(pcgi)->xcnt]; MYBUF(pcgi)->xcnt++; /* 'sprintf' format string is defined here. */ len += sprintf((char *)(buf+len),"<tr align=\"center\">"); if (tsoc->State <= TCP_STATE_CLOSED) { len += sprintf ((char *)(buf+len), "<td>%d</td><td>%s</td><td>-</td><td>-</td>" "<td>-</td><td>-</td></tr>\r\n", MYBUF(pcgi)->xcnt,state[tsoc->State]); } else if (tsoc->State == TCP_STATE_LISTEN) { len += sprintf ((char *)(buf+len), "<td>%d</td><td>%s</td><td>-</td><td>-</td>" "<td>%d</td><td>-</td></tr>\r\n", MYBUF(pcgi)->xcnt,state[tsoc->State],tsoc->LocPort); } else { len += sprintf ((char *)(buf+len), "<td>%d</td><td>%s</td><td>%d.%d.%d.%d</td>" "<td>%d</td><td>%d</td><td>%d</td></tr>\r\n", MYBUF(pcgi)->xcnt,state[tsoc->State], tsoc->RemIpAdr[0],tsoc->RemIpAdr[1], tsoc->RemIpAdr[2],tsoc->RemIpAdr[3], tsoc->RemPort,tsoc->LocPort,tsoc->AliveTimer); } /* Repeat for all TCP Sockets. */ if (MYBUF(pcgi)->xcnt == tcp_NumSocks) { break; } } if (MYBUF(pcgi)->xcnt < tcp_NumSocks) { /* Hi bit is a repeat flag. */ len |= 0x8000; } break; case 'd': /* System password - file 'system.cgi' */ switch (env[2]) { case '1': len = sprintf((char *)buf,(const char *)&env[4], http_EnAuth ? "Enabled" : "Disabled"); break; case '2': len = sprintf((char *)buf,(const char *)&env[4],http_auth_passw); break; } break; case 'e': /* Browser Language - file 'language.cgi' */ lang = http_get_lang(); if (strcmp ((const char *)lang, "en") == 0) { lang = "English"; } else if (strcmp ((const char *)lang, "en-us") == 0) { lang = "English USA"; } else if (strcmp ((const char *)lang, "en-gb") == 0) { lang = "English GB"; } else if (strcmp ((const char *)lang, "de") == 0) { lang = "German"; } else if (strcmp ((const char *)lang, "de-ch") == 0) { lang = "German CH"; } else if (strcmp ((const char *)lang, "de-at") == 0) { lang = "German AT"; } else if (strcmp ((const char *)lang, "fr") == 0) { lang = "French"; } else if (strcmp ((const char *)lang, "sl") == 0) { lang = "Slovene"; } else { lang = "Unknown"; } len = sprintf((char *)buf,(const char *)&env[2],lang,http_get_lang()); break; case 'f': /* LCD Module control - file 'lcd.cgi' */ switch (env[2]) { case '1': len = sprintf((char *)buf,(const char *)&env[4],lcd_text[0]); break; case '2': len = sprintf((char *)buf,(const char *)&env[4],lcd_text[1]); break; } break; case 'g': /* AD Input - file 'ad.cgi' */ switch (env[2]) { case '1': adv = AD_in (0); len = sprintf((char *)buf,(const char *)&env[4],adv); break; case '2': len = sprintf((char *)buf,(const char *)&env[4],(float)adv*3.3/4096); break; case '3': adv = (adv * 100) / 4096; len = sprintf((char *)buf,(const char *)&env[4],adv); break; } break; case 'x': /* AD Input - xml file 'ad.cgx' */ adv = AD_in (0); len = sprintf((char *)buf,(const char *)&env[1],adv); break; case 'y': /* Button state - xml file 'button.cgx' */ len = sprintf((char *)buf,"<checkbox><id>button%c</id><on>%s</on></checkbox>", env[1],(get_button () & (1 << (env[1]-'0'))) ? "true" : "false"); break; } return ((U16)len); }
// Generate dynamic web data from a script line. uint32_t cgi_script (const char *env, char *buf, uint32_t buflen, uint32_t *pcgi) { TCP_INFO *tsoc; const char *lang; uint32_t len = 0; uint8_t id; static uint32_t adv; switch (env[0]) { // Analyze a 'c' script line starting position 2 case 'a' : // Network parameters from 'network.cgi' switch (env[2]) { case 'i': // Write local IP address len = sprintf (buf, &env[4], LocM.IpAdr[0], LocM.IpAdr[1], LocM.IpAdr[2], LocM.IpAdr[3]); break; case 'm': // Write local network mask len = sprintf (buf, &env[4], LocM.NetMask[0], LocM.NetMask[1], LocM.NetMask[2], LocM.NetMask[3]); break; case 'g': // Write default gateway IP address len = sprintf (buf, &env[4], LocM.DefGW[0], LocM.DefGW[1], LocM.DefGW[2], LocM.DefGW[3]); break; case 'p': // Write primary DNS server IP address len = sprintf (buf, &env[4], LocM.PriDNS[0], LocM.PriDNS[1], LocM.PriDNS[2], LocM.PriDNS[3]); break; case 's': // Write secondary DNS server IP address len = sprintf (buf, &env[4], LocM.SecDNS[0], LocM.SecDNS[1], LocM.SecDNS[2], LocM.SecDNS[3]); break; } break; case 'b': // LED control from 'led.cgi' if (env[2] == 'c') { // Select Control len = sprintf (buf, &env[4], LEDrun ? "" : "selected", LEDrun ? "selected" : "" ); break; } // LED CheckBoxes id = env[2] - '0'; if (id > 7) { id = 0; } id = 1 << id; len = sprintf (buf, &env[4], (P2 & id) ? "checked" : ""); break; case 'c': // TCP status from 'tcp.cgi' while ((len + 150) < buflen) { tsoc = &tcp_socket[MYBUF(pcgi)->xcnt]; MYBUF(pcgi)->xcnt++; // 'sprintf' format string is defined here len += sprintf (buf+len, "<tr align=\"center\">"); if (tsoc->State <= tcpStateCLOSED) { len += sprintf (buf+len, "<td>%d</td><td>%s</td><td>-</td><td>-</td>" "<td>-</td><td>-</td></tr>\r\n", MYBUF(pcgi)->xcnt,state[tsoc->State]); } else if (tsoc->State == tcpStateLISTEN) { len += sprintf (buf+len, "<td>%d</td><td>%s</td><td>-</td><td>-</td>" "<td>%d</td><td>-</td></tr>\r\n", MYBUF(pcgi)->xcnt, state[tsoc->State], tsoc->LocPort); } else { len += sprintf (buf+len, "<td>%d</td><td>%s</td><td>%d.%d.%d.%d</td>" "<td>%d</td><td>%d</td><td>%d</td></tr>\r\n", MYBUF(pcgi)->xcnt, state[tsoc->State], tsoc->RemIpAdr[0], tsoc->RemIpAdr[1], tsoc->RemIpAdr[2], tsoc->RemIpAdr[3], tsoc->RemPort, tsoc->LocPort, tsoc->AliveTimer); } // Repeat for all TCP Sockets if (MYBUF(pcgi)->xcnt == tcp_NumSocks) { break; } } if (MYBUF(pcgi)->xcnt < tcp_NumSocks) { // Hi bit is a repeat flag len |= (1u << 31); } break; case 'd': // System password from 'system.cgi' switch (env[2]) { case '1': len = sprintf (buf, &env[4], http_EnAuth ? "Enabled" : "Disabled"); break; case '2': len = sprintf (buf, &env[4], http_auth_passw); break; } break; case 'e': // Browser Language from 'language.cgi' lang = http_server_get_lang (); if (strncmp (lang, "en", 2) == 0) { lang = "English"; } else if (strncmp (lang, "de", 2) == 0) { lang = "German"; } else if (strncmp (lang, "fr", 2) == 0) { lang = "French"; } else if (strncmp (lang, "sl", 2) == 0) { lang = "Slovene"; } else { lang = "Unknown"; } len = sprintf (buf, &env[2], lang, http_server_get_lang()); break; case 'f': // LCD Module control from 'lcd.cgi' switch (env[2]) { case '1': len = sprintf (buf, &env[4], lcd_text[0]); break; case '2': len = sprintf (buf, &env[4], lcd_text[1]); break; } break; case 'g': // AD Input from 'ad.cgi' switch (env[2]) { case '1': adv = AD_in (0); len = sprintf (buf, &env[4], adv); break; case '2': len = sprintf (buf, &env[4], (float)adv*3.3f/4096); break; case '3': adv = (adv * 100) / 4096; len = sprintf (buf, &env[4], adv); break; } break; case 'x': // AD Input from 'ad.cgx' adv = AD_in (0); len = sprintf (buf, &env[1], adv); break; case 'y': // Button state from 'button.cgx' len = sprintf (buf, "<checkbox><id>button%c</id><on>%s</on></checkbox>", env[1], (get_button () & (1 << (env[1]-'0'))) ? "true" : "false"); break; } return (len); }
U16 tnet_process_cmd (U8 *cmd, U8 *buf, U16 buflen, U32 *pvar) { /* This is a Telnet Client callback function to make a formatted output */ /* for 'stdout'. It returns the number of bytes written to the out buffer.*/ /* Hi-bit of return value (len is or-ed with 0x8000) is a disconnect flag.*/ /* Bit 14 (len is or-ed with 0x4000) is a repeat flag for the Tnet client.*/ /* If this bit is set to 1, the system will call the 'tnet_process_cmd()' */ /* again with parameter 'pvar' pointing to a 4-byte buffer. This buffer */ /* can be used for storing different status variables for this function. */ /* It is set to 0 by Telnet server on first call and is not altered by */ /* Telnet server for repeated calls. This function should NEVER write */ /* more than 'buflen' bytes to the buffer. */ /* Parameters: */ /* cmd - telnet received command string */ /* buf - Telnet transmit buffer */ /* buflen - length of this buffer (500-1400 bytes - depends on MSS) */ /* pvar - pointer to local storage buffer used for repeated loops */ /* This is a U32 variable - size is 4 bytes. Value is: */ /* - on 1st call = 0 */ /* - 2nd call = as set by this function on first call */ TCP_INFO *tsoc; REMOTEM rm; U32 val,ch,temp; U16 len = 0; switch (MYBUF(pvar)->id) { case 0: /* First call to this function, the value of '*pvar' is 0 */ break; case 1: /* Repeated call, command 'MEAS' measurements display. */ while (len < buflen-80) { /* Let's use as much of the buffer as possible. */ /* This will produce less packets and speedup the transfer. */ len += sprintf ((char *)(buf+len), "\r\n%4d", MYBUF(pvar)->idx); for (val = 0; val < 8; val++) { len += sprintf ((char *)(buf+len), "%7d", AD_in(val)); } if (++MYBUF(pvar)->idx >= MYBUF(pvar)->nmax) { /* OK, we are done. */ return (len); } } /* Request a repeated call, bit 14 is a repeat flag. */ return (len | 0x4000); case 2: /* Repeated call, TCP status display. */ while (len < buflen-80) { /* Let's use as much of the buffer as possible. */ /* This will produce less packets and speedup the transfer. */ if (MYBUF(pvar)->idx == 0) { len += str_copy (buf, (U8 *)tcp_stat); } tsoc = &tcp_socket[MYBUF(pvar)->idx]; len += sprintf ((char *)(buf+len), "\r\n%9d %10s ", MYBUF(pvar)->idx, state[tsoc->State]); if (tsoc->State <= TCP_STATE_CLOSED) { len += sprintf ((char *)(buf+len), " - - - -\r\n"); } else if (tsoc->State == TCP_STATE_LISTEN) { len += sprintf ((char *)(buf+len), " - - %5d -\r\n", tsoc->LocPort); } else { /* First temporary print for alignment. */ sprintf ((char *)(buf+len+16),"%d.%d.%d.%d",tsoc->RemIpAdr[0], tsoc->RemIpAdr[1],tsoc->RemIpAdr[2],tsoc->RemIpAdr[3]); len += sprintf ((char *)(buf+len),"%15s %5d %5d %4d\r\n", buf+len+16,tsoc->RemPort,tsoc->LocPort,tsoc->AliveTimer); } if (++MYBUF(pvar)->idx >= tcp_NumSocks) { /* OK, we are done, reset the index counter for next callback. */ MYBUF(pvar)->idx = 0; /* Setup a callback delay. This function will be called again after */ /* delay has expired. It is set to 20 system ticks 20 * 100ms = 2 sec. */ tnet_set_delay (20); break; } } /* Request a repeated call, bit 14 is a repeat flag. */ return (len |= 0x4000); } /* Simple Command line parser */ len = strlen ((const char *)cmd); if (tnet_ccmp (cmd, "LED") == __TRUE) { /* 'LED' command received */ if (len >= 5) { sscanf ((const char *)(cmd+4),"%x", &val); LED_out (val); len = 0; if (LEDrun == __TRUE) { len = str_copy (buf," --> Running Lights OFF"); LEDrun = __FALSE; } return (len); } len = 0; if (LEDrun == __FALSE) { len = str_copy (buf," --> Running Lights ON"); LEDrun = __TRUE; } return (len); } if (tnet_ccmp (cmd, "ADIN") == __TRUE) { /* 'ADIN' command received */ if (len >= 6) { sscanf ((const char *)(cmd+5),"%d",&ch); val = AD_in (ch); len = sprintf ((char *)buf,"\r\n ADIN %d = %d",ch,val); return (len); } } if (tnet_ccmp (cmd, "BYE") == __TRUE) { /* 'BYE' command, send message and disconnect */ len = str_copy (buf, "\r\nDisconnect...\r\n"); /* Hi bit of return value is a disconnect flag */ return (len | 0x8000); } if (tnet_ccmp (cmd, "PASSW") == __TRUE && tnet_EnAuth) { /* Change the system password. */ if (len == 5) { /* Disable password. */ tnet_auth_passw[0] = 0; } else { mem_copy (&tnet_auth_passw, &cmd[6], 20); } len = sprintf ((char *)buf, "\r\n OK, New Password: \"%s\"",tnet_auth_passw); return (len); } if (tnet_ccmp (cmd, "PASSWD") == __TRUE && tnet_EnAuth) { /* Only display the current system password. */ len = sprintf ((char *)buf, "\r\n System Password: \"%s\"",tnet_auth_passw); return (len); } if (tnet_ccmp (cmd, "MEAS") == __TRUE) { /* During the repeated call to this function, the 'cmd' buffer is locked, */ /* so we can use it for our temporary storage. Each Telnet session has its */ /* own buffer of size 96 bytes. We can use 95 bytes, last one is not free. */ /* Here the local storage '*pvar' is initialized to 0 by Telnet Server. */ MYBUF(pvar)->id = 1; if (len > 5) { /* We must be careful here, because data is overlaid. */ sscanf ((const char *)&cmd[5], "%d", &temp); MYBUF(pvar)->nmax = temp; } len = str_copy (buf,(U8 *)meas_header); if (MYBUF(pvar)->nmax) { /* Bit 14 is a repeat flag. */ len |= 0x4000; } return (len); } if (tnet_ccmp (cmd, "TCPSTAT") == __TRUE) { /* Display a TCP status similar to that in HTTP_Demo example. */ /* Here the local storage '*pvar' is initialized to 0 by Telnet Server. */ MYBUF(pvar)->id = 2; len = str_copy (buf, CLS); return (len | 0x4000); } if (tnet_ccmp (cmd, "RINFO") == __TRUE) { /* Display Remote Machine IP and MAC address. */ tnet_get_info (&rm); len = sprintf ((char *)buf,"\r\n Remote IP : %d.%d.%d.%d", rm.IpAdr[0],rm.IpAdr[1],rm.IpAdr[2],rm.IpAdr[3]); len += sprintf ((char *)(buf+len), "\r\n Remote MAC: %02X-%02X-%02X-%02X-%02X-%02X", rm.HwAdr[0],rm.HwAdr[1],rm.HwAdr[2], rm.HwAdr[3],rm.HwAdr[4],rm.HwAdr[5]); return (len); } if (tnet_ccmp (cmd, "HELP") == __TRUE || tnet_ccmp (cmd, "?") == __TRUE) { /* 'HELP' command, display help text */ len = str_copy (buf,(U8 *)tnet_help1); if (tnet_EnAuth) { len += str_copy (buf+len,(U8 *)tnet_help2); } len += str_copy (buf+len,(U8 *)tnet_help3); return (len); } /* Unknown command, display message */ len = str_copy (buf, "\r\n==> Unknown Command: "); len += str_copy (buf+len, cmd); return (len); }