Small Testprogram to have WebAccess via Webserver to a 433Mhz tranmitter to control remotly some devices from remote, with TFTP, NTP and RMF. This could be a base to develop applications.
Dependencies: ChaNFSSD TFTPServer RMFWeb
NewRMFWeb.cpp
- Committer:
- ED7418
- Date:
- 2014-06-06
- Revision:
- 0:51f1ef89ec7b
- Child:
- 1:809b59c7a800
File content as of revision 0:51f1ef89ec7b:
// (c) 2014 M.Haufe // Programm dient zum testweises // senden der RMF-Rollladencodes // via 433Mhz-ASK-Sender // - erweitert um web-funktionalität // - erweitert um JavaScript webinterface // - erweitert um integer von Website zu senden und via Termialfenster anzuzeigen // - Errorhandling Netzwerkverbindung zugefuegt // - Lerntaste zugefügt // - DIP-Schalter für Adresse 0...15 zugefügt // - Stop-Taste zugefügt // - zugewiesene IP-Adresse in sring konvertieren in abhängigkeit des dip-schalters // - kopieren der _rmf.htm in rmf_htm mit ersetzen der url's in die gegenwärtig gültigen (wird nicht mehr gebraucht !) // - rpc-funktionalitaet auf website mit bibliothek realisert, damit ok auch unter os-x // - adressübermittlung der website und umsetzen in entsprechendes kommando // - andere pins zugeordnet für dip-schalter tasten, led damit platz und anschlusspins für sd-card frei wird // - uSD-Slot zugefügt // - TFTP-Server zugefügt // - Watchdog zugefügt // - Grundlage zur Getupverwaltung über <cfg.dat> Datei (SD) implementiert // - NTP-Zeitserver-Funktionalität // Stand : 25.04.2014 //WEB-Zugriffe via RPC oder Website //URL --> http://10.68.139.239:8020/rpc/ab_rpc/write%201 //URL --> http://10.68.139.239:8020/rpc/stp_rpc/write%201 //URL --> http://10.68.139.239:8020/rpc/auf_rpc/write%201 //URL --> http://10.68.139.239:8020/rpc/data_rpc/write%20123456789 //via auf dem MBED liegender Website URL --> http://10.68.139.239:8020/web/rmf.htm //via auf der SD-Card liegender Website URL --> http://10.68.139.239:8020/sd/rmf.htm #include "mbed.h" #include "SDFileSystem.h" #include "TFTPServer.h" #include "EthernetNetIf.h" #include "HTTPServer.h" #include "RPCFunction.h" #include "SerialRPCInterface.h" #include "NTPClient.h" //192.168.178.67 extern "C" void mbed_mac_address ( char *s) { char mac [6]; mac [0]=0x0A; mac [1]=0xC1; mac [2]=0x10; mac [3]=0x51; mac [4]=0x0B; mac [5]=0xCA; memcpy (s, mac , 6); } NTPClient ntp; // define the NTP server TFTPServer *srv; // define the TFTP Server HTTPServer http; // define the http server Timer t; // used in main() to send debug output every 2 seconds Serial *serial; // serial just for debugging SDFileSystem sd(p5, p6, p7, p8, "sd"); // only needed if you save to SD card EthernetNetIf *eth; // network device LocalFileSystem local("local"); // defining this makes MBED internal mem accessible LocalFileSystem web("local"); // defining this makes MBED internal mem accessible Ticker sample1; Timer ptim;// timer für pulsdauermessungen aktiviert //Hardware-Init DigitalIn adr_bit3(p9);//Adresse Bit 3 DigitalIn adr_bit2(p10);//Adresse Bit 2 DigitalIn adr_bit1(p11);//Adresse Bit 1 DigitalIn adr_bit0(p12);//Adresse Bit 0 DigitalIn ser_code2(p13);//auf DigitalIn ser_code3(p14);//stop DigitalIn ser_code1(p15);//ab DigitalIn learn_button(p16);//Lern-Taste DigitalOut web_access_led(p17); //ausgang für led wenn zugriff über javascript der website erfolgt DigitalOut sd_status_led(p18); // sd-status wird gesetzt, wenn sd-test erfolgreich war DigitalOut test_out1(p19); //ausgang für flankenerkennung deklarieren DigitalOut test_out2(p20); //test-output deklarieren DigitalOut myled1(LED1,"led1"); //Led 1 deklarieren DigitalOut led2(LED2, "led2"); DigitalOut led3(LED3, "led3"); DigitalOut led4(LED4, "led4"); //allgemeine variablen char tmp1_char; int tmp1_int; //variablen ethernetverbindung char net_ok; // ergebnis der ethernet verbindung char try_net; // zählschleife für ethernet verbindung int port_adr=8020; // vorgabe der portadresse des http-servers char ip_adr_str[]= "http://xxx.xxx.xxx.xxx:xxxx ";//platzhalter für ip-adresse //rpc-variablen char rpc_ab_web; char rpc_stp_web; char rpc_auf_web; int rpc_data_web; char rpc_cmd_web; char old_rpc_cmd_web; //variablen um eine stehende verbindung zwischen browser und mbed zu erkennen int rpc_mbed_con; char rpc_browser_con; char browser_connected; char old_browser_connected; //tftp-variablen char wd_tim_cause=0; char sd_ok; char en_tftp_srv=0;//entweder funk(=0) oder tftp(=1)-funktionalität möglich int filecounter = 0; // incoming files char filename[256]; // to display filenames //remotecontrol-variablen char snd_start; int snd_req_activ; char act_frame_cnt; char frame_bit_ont; int bit_val; char bit_index; char hlp_bit_idx; char cmd_str_len; char cmd_str_len1; char target_frame_cnt; char main_loop_cnt; char fb_adr; char strg1[]=" "; char cmd_strg_buffer []="0000000000000000000000000000000000000000"; char fb_id_strg[]="0001100100100000011111001101";//externe fb-id char fb_adr_strg[]="0000"; char fb_cmd_up_strg[]="0010001"; char fb_cmd_dn_strg[]="0110011"; char fb_cmd_stp_strg[]="1010101"; char fb_cmd_lrn_strg[]="1001100"; // "0010101001000000010100100001000100010001" // IIIIIIIIIIIIIIIIIIIIIIIIIIIICCCCLBBBBBBB //FB-ID xxxxxxxxxxxxxxxxxxxxxxxxxxxx //FB-Ch xxxx //FB-Lrn x //FB-Cmd xxxxxxx //eingelernte Kanäle : //0 = alle //1 = Terrasse Tür //2 = Terasse Fenster //3 = Küche //4 = Zimmer Jenny links //5 = Zimmer Jenny rechts //6 = Zimmer Bine //vorbereitet : //7 = HH-Gaube //8 = HH-Giebel //9 = HH-Dach //angedacht : //10 = Simu-Bad //11 = Simu-Gäste-WC //****************************************** Anfang Subroutinen ******************************************** class Watchdog { public: // Load timeout value in watchdog timer and enable void kick(float s) { LPC_WDT->WDCLKSEL = 0x1; // Set CLK src to PCLK uint32_t clk = SystemCoreClock / 16; // WD has a fixed /4 prescaler, PCLK default is /4 LPC_WDT->WDTC = s * (float)clk; LPC_WDT->WDMOD = 0x3; // Enabled and Reset kick(); } // "kick" or "feed" the dog - reset the watchdog timer // by writing this required bit pattern void kick() { LPC_WDT->WDFEED = 0xAA; LPC_WDT->WDFEED = 0x55; } }; // Setup the watchdog timer Watchdog wdt; void get_NTPtime(){ time_t ctTime; //printf("NTP setTime...\n\r"); Host server(IpAddr(), 123, "pool.ntp.org"); ntp.setTime(server); ctTime = time(NULL); ctTime = ctTime+7200;// +2:00 in sec Sommerzeit Deutschland //printf("\n\rTime is now (UTC): %d %s\n\r",ctTime,ctime(&ctTime)); printf("Time is now : %s\n\r", ctime(&ctTime));// anzeige der aktuellen ntp-zeit } char test_sd(){ // test SD card (TFTP server can work without it) sd_ok=0; // 0 = noch kein sd-test durchgeführt sd_status_led = 0; // sd-status-led ausschalten //printf("TEST SD...\n\r"); FILE *fp = fopen("/sd/test.txt", "wb"); if ( fp == NULL ){ sd_ok=99;}// 99 = signalisiert sd-fehler else { sd_ok=1;// 1 = sd-test ok sd_status_led = 1; // sd-status-led einschalten fclose(fp); } remove("/sd/test.txt"); return sd_ok; } void write_defconfig_sd(){ //default-configuration auf sd in datei -cfg.dat- schreiben if(sd_ok==1){ //printf("Write DefConfig to SD...\n\r"); FILE *fp = fopen("/sd/cfg.dat", "wb"); tmp1_char=0;fputc(tmp1_char,fp);//einstellung für >en_tftp_srv< fclose(fp); } } void write_config_sd(){ //gegenwärtige configuration auf sd in datei -cfg.txt- schreiben if(sd_ok==1){ //printf("Write ActConfig to SD...\n\r"); FILE *fp = fopen("/sd/cfg.dat", "wb"); fputc(en_tftp_srv,fp);//gegnwärtige einstellung für >en_tftp_srv< fclose(fp); } } void read_config_sd(){ //gegenwärtige configuration auf sd in datei -cfg.txt- schreiben if(sd_ok==1){ //printf("Load Config from SD...\n\r"); FILE *fp = fopen("/sd/cfg.dat", "rb"); en_tftp_srv=fgetc(fp);//einstellung für >en_tftp_srv< laden fclose(fp); } } void getdipadr()//ermittelt die gegenwärtig mit dip schalter eingestellte adresse { fb_adr=0; if (adr_bit3>0){fb_adr_strg[0]='1';fb_adr=fb_adr+8;} else {fb_adr_strg[0]='0';} if (adr_bit2>0){fb_adr_strg[1]='1';fb_adr=fb_adr+4;} else {fb_adr_strg[1]='0';} if (adr_bit1>0){fb_adr_strg[2]='1';fb_adr=fb_adr+2;} else {fb_adr_strg[2]='0';} if (adr_bit0>0){fb_adr_strg[3]='1';fb_adr=fb_adr+1;} else {fb_adr_strg[3]='0';} } void getwebadr()//ermttelt die via web-commando ermittelte adresse und ueberschreibt >fb_adr_strg< mit aktuellem wert { fb_adr=0; if (rpc_ab_web>0){fb_adr = rpc_ab_web-1;} if (rpc_stp_web>0){fb_adr = rpc_stp_web-1;} if (rpc_auf_web>0){fb_adr = rpc_auf_web-1;} switch(fb_adr) { case 0: strcpy(fb_adr_strg,"0000"); break; case 1: strcpy(fb_adr_strg,"0001"); break; case 2: strcpy(fb_adr_strg,"0010"); break; case 3: strcpy(fb_adr_strg,"0011"); break; case 4: strcpy(fb_adr_strg,"0100"); break; case 5: strcpy(fb_adr_strg,"0101"); break; case 6: strcpy(fb_adr_strg,"0110"); break; default: strcpy(fb_adr_strg,"1111"); break; } } void sample_sub() //timer-isr { test_out1 = 1;//test_out-ausgang setzen wait_us(10); test_out1 = 0;//test_out-ausgang löschen if (snd_start){//snd_req_activ >0 spiegelt eine anforderung zum senden wieder if (snd_req_activ==0){snd_req_activ=1;} } else if (snd_req_activ==1){ snd_req_activ=2; act_frame_cnt=0; } if(snd_req_activ>1){snd_req_activ++;} if (snd_req_activ==3){//startpuls beginnen ~5.2ms lang mit anpassung des isr-zeitintervals test_out2 = 1;sample1.attach(&sample_sub,0.000522); act_frame_cnt++; } if (snd_req_activ==13){//startpuls beenden mit anpassung des isr-zeitintervals bis zum 1.Datenbit test_out2 = 0; sample1.attach(&sample_sub,0.000425); hlp_bit_idx=0; bit_index=0; cmd_str_len=strlen(cmd_strg_buffer); cmd_str_len1=cmd_str_len*2; cmd_str_len=cmd_str_len1+17; } if (snd_req_activ<cmd_str_len){//vorher 97 if (snd_req_activ>=17){ hlp_bit_idx=!hlp_bit_idx; if (hlp_bit_idx!=0){ strg1[0]=cmd_strg_buffer [bit_index]; bit_val= atoi(strg1); bit_index++; test_out2 = 1; if (bit_val==0){sample1.attach(&sample_sub,0.000345);} else {sample1.attach(&sample_sub,0.000710);} } else { test_out2 = 0; if (bit_val==0){sample1.attach(&sample_sub,0.000715);} else {sample1.attach(&sample_sub,0.000350);} } } } if (snd_req_activ==cmd_str_len+23){//defineirt laenge vom low-pegel zwischen 2 frames if (act_frame_cnt<target_frame_cnt){snd_req_activ=2;led2=!led2;} else{ led2=0;led3=0;led4=0;} } if (snd_req_activ>200){ snd_req_activ = 0; test_out2 = 0; sample1.attach(&sample_sub,0.0005); } } //****************************************** Ende Subroutinen ******************************************** int main() { // configure serial terminal serial = new Serial(USBTX, USBRX); serial->baud(9600); // Watchdog auslösegrund auslesen und wd-timeout initialisieren if ((LPC_WDT->WDMOD >> 2) & 1) wd_tim_cause = 1; else wd_tim_cause = 2; wdt.kick(30.0);// setzen des wd-timeout in sec test_sd(); // sd-speicher testen read_config_sd(); // configuration von sd einlesen //terminalausgabe beim start printf("\x1B\x48"); //cursor home printf("\x1B\x4A"); //lösche bildschirm printf("\n\r"); printf("RMFWeb (Rev25042014.0700) is starting...\n\r"); //Textausgabe mit zeilenvorschub if (sd_ok==1)printf("SD:Filesystem ok\n\r");else printf("SD:Filesystem fail\n\r");// info über wd-cause ausgeben if (wd_tim_cause==1)printf("WDT:SoftReset\n\r");else printf("WDT:HardReset\n\r");// info über wd-cause ausgeben if (en_tftp_srv==0)printf("TFTPmode:off\n\r");else printf("TFTPmode:activ\n\r");//info betriebsart TFTP oder Funk ausgeben // Ethernet verbindungsaufbau EthernetNetIf eth; EthernetErr ethErr; try_net=1;net_ok=0; do { printf("Looking for Ethernet %d...\n\r", try_net); wdt.kick();// watchdog aufziehen ethErr = eth.setup(); if(ethErr==0){net_ok=1;break;} ++try_net; } while (try_net<=3); if (net_ok==1){// netzwerk verbunden http.bind(port_adr); printf("Connected-Status: OK \n\r"); const char* hwAddr = eth.getHwAddr(); IpAddr ethIp = eth.getIp(); snprintf(ip_adr_str,27,"http://%d.%d.%d.%d:%d", ethIp[0], ethIp[1], ethIp[2], ethIp[3],port_adr);//url-string erzegen printf("%s",ip_adr_str);;printf("\n\r");//ip/url ausgeben printf("Server is online! \n\r");// info das server nicht verbunden ist get_NTPtime(); } else{//netzwerk nicht verbunden printf("Ethernet Error %d\n\r", ethErr);// sonstiger fehler printf("Server is offline! \n\r");// info das server nicht verbunden ist rpc_browser_con=0; en_tftp_srv=0;//tftp-server ausschalten } FSHandler::mount("/local", "/web"); // mounting /web als MBED root pfad FSHandler::mount("/sd", "/sd"); // mounting /SD als SD-Card root pfad Base::add_rpc_class<DigitalOut>(); Base::add_rpc_class<DigitalIn>(); Base::add_rpc_class<AnalogIn>(); http.addHandler<SimpleHandler>("/hello"); http.addHandler<FSHandler>("/");// default handler http.addHandler<FSHandler>("/web"); http.addHandler<FSHandler>("/sd");// default handler http.addHandler<RPCHandler>("/rpc"); RPCVariable<char> RPCrpc_ab_web(&rpc_ab_web, "ab_rpc");//URL --> http://10.68.139.239:8020/rpc/ab_rpc/write%201 RPCVariable<char> RPCrpc_stp_web(&rpc_stp_web, "stp_rpc");//URL --> http://10.68.139.239:8020/rpc/stp_rpc/write%201 RPCVariable<char> RPCrpc_auf_web(&rpc_auf_web, "auf_rpc");//URL --> http://10.68.139.239:8020/rpc/auf_rpc/write%201 RPCVariable<int> RPCrpc_data_web(&rpc_data_web, "data_rpc");//URL --> http://10.68.139.239:8020/rpc/data_rpc/write%201 RPCVariable<int> RPCrpc_mbed_con(&rpc_mbed_con, "mbed_rpc"); // eine art watchdog damit website eine stehende verbindung zum mbed erkennt RPCVariable<char> RPCrpc_browser_con(&rpc_browser_con, "brow_rpc"); // eine rt watchdog um gegenwärtigen browswerzugriff zu erkennen RPCVariable<char> RPCrpc_cmd_web(&rpc_cmd_web, "cmd_rpc");// zum übergeben von kommandos der website an mbed, z.b. resetanforderung //via auf dem MBED liegender Website URL --> http://10.68.139.239:8020/web/rmf.htm //via auf der SD-Card liegender Website URL --> http://10.68.139.239:8020/sd/rmf.htm wdt.kick(5.0);// setzen des wd-timeout in sec target_frame_cnt=16;//anzahl der zu sendenen frames nach einer anforderung web_access_led =0;// webaccess-led ausschalten browser_connected=0; old_browser_connected=0; main_loop_cnt=0; test_out2 = 0; fb_adr=0; if(en_tftp_srv>0){ sample1.detach(); srv = new TFTPServer("/sd/"); printf("TFTP:Server listen...\n\r"); } else{ printf("RMF-Mode activ...\n\r"); sample1.attach(&sample_sub,0.0005);//500us timer-isr ptim.reset(); //timer löschen } t.start(); while (1) { Net::poll(); if(en_tftp_srv>0){ if (serial->readable()) { int c = serial->getc(); switch (c) { case 's': srv->suspend(); break; case 'r': srv->resume(); break; } } if (srv->fileCnt() > filecounter) { filecounter = srv->fileCnt(); srv->getFilename(filename); printf("TFTP:New file: %s\n\r", filename); } } if (t.read() > 0.5) { t.reset(); snd_start=0; myled1 = !myled1;//alive-led und variable hochzählen -> wird im browser angezeigt rpc_mbed_con++;// variable einfach nur fortwaehrend inkrementieren damit website stehende verbindung zum mbed erkennen kann if (rpc_mbed_con>255){rpc_mbed_con=0;} // einen verbundenen browser detektieren old_browser_connected = browser_connected; browser_connected=0; if (rpc_browser_con>1){// rpc_browser_con wird vom verbundenen browser immer wieder auf 3 gesetzt rpc_browser_con--;// hier wird der wert immer wieder dekrementert browser_connected=1;}// sofern wert >1 bleibt, gilt verbindung als hergestellt if (old_browser_connected>browser_connected){printf("WebBrowser disconnected \n\r");} if (browser_connected>old_browser_connected){printf("WebBrowser connected \n\r");} if (browser_connected==1){web_access_led=1;} else {web_access_led=0;}// brwoser-verbindung via led anzeige if(en_tftp_srv==0){ if (rpc_ab_web>0 or ser_code1){//ser_code1 --> ABWAERTS getdipadr(); //DIP-Schalter decodieren if (rpc_ab_web>0){getwebadr();} // wenn web-commando vorliegt, diese ermitteln strcpy(cmd_strg_buffer,fb_id_strg); //FB-Code in buffer kopieren strcat(cmd_strg_buffer,fb_adr_strg);//FB-Adresse anhaengen strcat(cmd_strg_buffer,"0");//Lern-Bit loeschen strcat(cmd_strg_buffer,fb_cmd_dn_strg);//auf-Kommando anhaengen if (ser_code1){printf("AB-Taste <Adresse:>" );} // ausgabe der befehlsquelle, hier taster if (rpc_ab_web>0){printf("AB-WebCommand <Adresse:>" );}// ausgabe der befehlsquelle, hier web-command printf(fb_adr_strg);printf("\n\r"); snd_start=1; rpc_ab_web=0;//web-request löschen led3=1; } } if(en_tftp_srv==0){ if (rpc_stp_web>0 or ser_code3){//ser_code3 --> STOP getdipadr(); //DIP-Schalter decodieren if (rpc_stp_web>0){getwebadr();} // wenn web-commando vorliegt, diese ermitteln strcpy(cmd_strg_buffer,fb_id_strg); //FB-Code in buffer kopieren strcat(cmd_strg_buffer,fb_adr_strg);//FB-Adresse anhaengen strcat(cmd_strg_buffer,"0");//Lern-Bit loeschen strcat(cmd_strg_buffer,fb_cmd_stp_strg);//auf-Kommando anhaengen if (ser_code3){printf("STOP-Taste <Adresse:>" );} // ausgabe der befehlsquelle, hier taster if (rpc_stp_web>0){printf("STOP-WebCommand <Adresse:>" );}// ausgabe der befehlsquelle, hier web-command printf(fb_adr_strg);printf("\n\r"); snd_start=1; rpc_stp_web=0;//web-request löschen led3=1;led4=1; } } if(en_tftp_srv==0){ if (rpc_auf_web>0 or ser_code2){//ser_code2 --> AUFWAERTS getdipadr(); //DIP-Schalter decodieren if (rpc_auf_web>0){getwebadr();} // wenn web-commando vorliegt, diese ermitteln strcpy(cmd_strg_buffer,fb_id_strg); //FB-Code in buffer kopieren strcat(cmd_strg_buffer,fb_adr_strg);//FB-Adresse anhaengen strcat(cmd_strg_buffer,"0");//Lern-Bit loeschen strcat(cmd_strg_buffer,fb_cmd_up_strg);//auf-Kommando anhaengen if (ser_code2){printf("AUF-Taste <Adresse:>" );} // ausgabe der befehlsquelle, hier taster if (rpc_auf_web>0){printf("AUF-WebCommand <Adresse:>" );}// ausgabe der befehlsquelle, hier web-command printf(fb_adr_strg);printf("\n\r"); snd_start=1; rpc_auf_web=0;//web-request löschen led4=1; } } if(en_tftp_srv==0){ if (learn_button){//Ausgabe info wenn learn-button betätigt wird printf("LearnButton pressed\n\r"); getdipadr(); //DIP-Schalter decodieren if (fb_adr>0){ strcpy(cmd_strg_buffer,fb_id_strg); //FB-Code in buffer kopieren strcat(cmd_strg_buffer,fb_adr_strg);//FB-Adresse anhaengen strcat(cmd_strg_buffer,"1");//Lern-Bit anhaengen strcat(cmd_strg_buffer,fb_cmd_lrn_strg);//Lern-Kommando anhaengen snd_start=1; led2=1;led3=1;led4=1; printf(cmd_strg_buffer);printf("\n\r"); } else {printf("Adresse muss <> NULL sein! \n\r");} } } // kommandoverarbeitung via rpc-variable via browser gesetzt if (rpc_cmd_web!=1){wdt.kick();}// watchdog zyklisch aufziehen (nur wenn rpc_cmd_web <> 1 ist) if (old_rpc_cmd_web!=rpc_cmd_web){//ausgabe des commandos welcher vom browser übermittelt wird if (rpc_cmd_web==1){printf("WebCmd:Reset request... \n\r");}//Resetrequest mit (=1) if (rpc_cmd_web==2){printf("Start as TFTP-Server \n\r");en_tftp_srv=1;write_config_sd();rpc_cmd_web=1;}//in config auf tftp setzen und neu starten (=2) if (rpc_cmd_web==3){printf("Start as RMF-Transmitter \n\r");en_tftp_srv=0;write_config_sd();rpc_cmd_web=1;}//in config auf rmf setzen und neu starten if (rpc_cmd_web==5){printf("WebCmd:Write DefCfg to SD... \n\r");write_defconfig_sd();rpc_cmd_web=0;}//schreibe DefCfg auf SD mit (=5) if (rpc_cmd_web==6){printf("WebCmd:Write ActCfg to SD... \n\r");write_config_sd();rpc_cmd_web=1;}//schreibe ActCfg auf SD und neu starten mit (=6) if (rpc_cmd_web==7){printf("WebCmd:Load Config from SD... \n\r");read_config_sd();rpc_cmd_web=1;}//lade ActCfg von SD und starte neu mit (=7) if (rpc_cmd_web==8){printf("WebCmd:Read UTC from NTP-Server... \n\r");get_NTPtime();rpc_cmd_web=0;}//lade utc vom ntp-server mit (=8) old_rpc_cmd_web=rpc_cmd_web; } if(en_tftp_srv>0){ TFTPServerState state = srv->State(); switch(state) { case listen: //printf("MAIN: TFTP listen\n\r"); break; case reading: srv->getFilename(filename); printf("TFTP:Reading file: %s\n\r", filename); break; case writing: srv->getFilename(filename); printf("TFTP:Writing file: %s\n\r", filename); break; case error: printf("TFTP:Error\n\r"); break; case suspended: printf("TFTP:Suspended\n\r"); break; default: printf("TFTP:Unknown status\n\r"); break; } } } } }