Important Announcement
PubHTML5 Scheduled Server Maintenance on (GMT) Sunday, June 26th, 2:00 am - 8:00 am.
PubHTML5 site will be inoperative during the times indicated!

Home Explore RECS 101: UN WEB SERVER EMBEDDED PER APPLICAZIONI DI CONTROLLO REMOTO TRAMITE TCP/IP Terza parte - Fare Elettronica n. 216 - Giugno 2003 - Anno 19

RECS 101: UN WEB SERVER EMBEDDED PER APPLICAZIONI DI CONTROLLO REMOTO TRAMITE TCP/IP Terza parte - Fare Elettronica n. 216 - Giugno 2003 - Anno 19

Published by Cristian Randieri, PhD, 2015-12-23 03:56:41

Description: Contacts: Mobile +39 335-1880035 MSN: [email protected] | SKYPE: intellisystem_technologies email: [email protected] web: http://www.intellisystem.it Facebook https://www.facebook.com/intellisystem Linkedin https://www.linkedin.com/in/cristianrandieri Twitter https://twitter.com/C_Randieri ResearchGate: http://www.researchgate.net/profile/Cristian_Randieri Academia.edu: https://unict.academia.edu/CristianRandieri YouTube Channel: https://www.youtube.com/c/intellisystemit Google+: https://plus.google.com/+IntellisystemIt

Search

Read the Text Version

AUTOMAZIONERECS 101: UN WEB SERVEREMBEDDED PER APPLICAZIONIDI CONTROLLORteErzMa pOarTteO TRAMITE TCP/IP di Cristian Randieri [email protected] questa terza parte della presentazione del dispositivo RECS 101 vengono affrontatii seguenti argomenti: il protocollo di comunicazione implementato in RECS 101 edesempi di metodologie per la progettazione di applicazioni personalizzate mediantel’implementazione di socket Internet in C e in Java.PROTOCOLLO DI COMUNICAZIO- IP impostato su RECS 101 e la relativa • I/O Get Command: È il comando porta fissata alla 6001.RECS 101 si mediante il quale l’interfaccia socketNE IMPLEMENTATO IN RECS 101 occuperà dell’interpretazione dei interroga RECS 101 sullo stato delle comandi di controllo ricevuti o tra- proprie porte.RECS 101 effettua il controllo delle smessi dal dispositivo elettronico dasue porte digitali mediante un inter- controllare ad esso connesso. • I/O Get Command Responce: È ilfaccia basata sui socket di Internet. I comandi di controllo si suddividono comando di risposta mediante ilPer ottenere il controllo remoto delle in due categorie che identificano due quale RECS 101 comunica all’inter-porte di I/O attraverso Internet, è operazioni diverse: faccia socket lo stato delle sue portenecessario che l’interfaccia che gesti- di I/O.sce i socket venga implementata nelPC dell’utente che intende collegarsi Monitor Stato I/O Controllo dell’Outputa RECS 101 attraverso il protocollo Tramite quest’operazione è possibile Questo tipo di operazione, gestitaTCP/IP. avere informazioni inerenti lo stato di unicamente dal comando Output SetLa potenzialità di RECS 101 consiste tutte le linee di I/O contenute nelle Command è utilizzata dall’interfaccianel fatto che tale interfaccia può esse- due porte a 16 bit di RECS 101. I socket per settare i valori della portare implementata indifferentemente comandi relativi a quest’operazione d’Output di RECS 101. La tabella 1mediante un’ Applet Java (che viene sono essenzialmente due: riassume i comandi relativi alla comu-eseguita all’interno del Web Browserche si collega al dispositivo RECS 101) Figura 1: Possibili scenari d’implementazione dell’interfaccia di comunicazione socket di RECS 101o un’applicazione C/Java che utilizzi isocket di Internet (figura 1).Ovviamente per fare ciò occorre pro-gettarle adeguatamente aderendoallo standard fissato dalle regole dellasuite di protocolli TCP/IP. Tali interfac-ce si occuperanno quindi di inviare ericevere i comandi per il controllodelle porte di I/O attraverso l’indirizzo68 AUTOMAZIONE

AUTOMAZIONE una parola di 16 bytes. Di conseguenza l’utente dovrà inter- pretare solamente i primi 4 bytes del pacchetto ricevuto. Ciò è dovuto al fatto che, come dettoFigura 2: Schema funzionale per la gestione di un dispositivo elettronico tramite RECS 101 in precedenza, la trasmissione di que- ste informazioni avviene mediante i socket che operano tramite il protocol- lo TCP/IP che a sua volta opera sullo standard Ethernet. Poiché lo standard Ethernet impone una lunghezza minima del pacchetto di 64 bytes (inclusi i gli headers IP e TCP) [1], e considerando il fatto che nel caso in cui venga generato un pac-Figura 3: Comandi di controllo di RECS 101 chetto la cui lunghezza minima è infe- riore ai 64 bytes questi viene scartato, bisogna arrivare alla conclusione che anche se RECS ne avrebbe di bisogno solamente 4 si è costretti ad usarne16, di conseguenza, l’utente dovrà inter- pretare solamente i primi 4 bytes del pacchetto ricevuto (tabella 4).Figura 4: Comando di controllo della porta di Output di RECS 101 Controllo dei comandi di Outputnicazione e i tipi di messaggi che ven- sia acceso quando a quest’ultima viene Questo tipo di comando viene utilizza-gono scambiati tra l’interfaccia socket inviato uno zero logico. Se adesso con- to in tutti quei casi in cui si vuole modi-ed il dispositivo RECS 101. sideriamo il caso in cui i bit 0,2,4 e 10 ficare il valore di un bit della porta di della porta di Output siano nello stato Output di RECS 101 senza che vengaMonitor dello stato di I/O logico alto e i bit 1,3 e 5 della porta di generato un messaggio di conferma.Lo stato della porta di I/O di RECS 101 Input siano anch’essi nello stato logico La tabella 5 riporta il formato del rela-è controllato mediante comandi gesti- alto, RECS 101 alla ricezione del tivo comando “0x76” che si componeti tramite l’interfaccia socket che prov- comando “0x75” risponderà come di 4 bytes di cui il primo contiene ilvede a far dialogare il PC utente con descritto nella tabella 3. comando vero e proprio e gli altri dueRECS 101. A questo punto l’interfaccia socket tra rappresentano il nuovo stato che laPiù esattamente il comando che il PC RECS 101 ed il PC utente si occuperà porta d’Output dovrà assumere.utente deve inviare per ricevere da parte dell’interpretazione di questo valore Per esempio, supponiamo il caso in cuidi RECS 101 lo stato delle porte di I/O è visualizzandolo sul PC utente. si voglia modificare lo stato della portalo “0x75”, che si compone di un byte. d’Output di RECS 101 settando alloQuando RECS 101 riceverà tale Anche se i dati relativi allo stato delle stato logico “alto” i bit 0,1,2 e 3comando provvederà a comunicare lo porte di I/O sono contenuti in 4 byte, lasciando tutti gli altri nello stato logi-stato delle porte di I/O utilizzando 4 RECS 101 invierà all’interfaccia socket co “basso”. Allora poiché il corrispon-byte come riportato in tabella 2.Appare evidente che lo stato delle Tipo di operazione Comando Direzioneporte di I/O dipenderà dalla logica PC Utente RECS 101implementata dall’utilizzatore di RECS101. Per esempio, supponendo che il Monitor Stato I/O I/O Get Commandcircuito da interfacciare a RECS 101 sia I/O Get Command Responsestato progettato per lavorare secondo Controllo dell’Output Output Set Commandla tecnica “Active LOW” ciò equivale adire che un ipotetico diodo Led colle- Tabella 1: Comandi relativi alla comunicazione e i tipi di messaggi che vengono scambiati tra l’interfacciagato ad un’uscita della porta di Output socket ed il dispositivo RECS 101 AUTOMAZIONE 69

AUTOMAZIONETipo Numero di Byte 2 34 1Comando per monitorare lo stato delle porte di I/ORisposta contenete lo stato delle porte di I/O 0x75 Stato della porta di Input Stato della porta di Output Byte 1 Byte 2 Byte 3 Byte 4 MSB LSB MSB LSB Stato della porta di Input Stato della porta di OutputTabella 2: Controllo dello stato delle porte di I/O di RECS 10115 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0111110111110101000000000001010101111 | 1011 | 1110 | 1010 = 0xFBEA 0000 | 0000 | 0010 | 1010 = 0x002AStato della porta di Input Stato della porta di OutputTabella 3: Esempio di codifica dello stato della porta di I/Odente valore in esadecimale è 0x000F, rebbe essere utili per tutte quelle esi- Definite le variabili occorre inizializzareoccorrerà inviare a RECS 101 il valore genze di protezione e di riservatezza il Socket TCP mediante la chiamata allaesadecimale 76:00:0F come mostrato che escludano l’utilizzo di una procedura TCPSocketInit() che pernella tabella 6. tale interfaccia. brevità non viene riportata. Si passa Come primo esempio si riporta la pro- quindi ad inizializzare il buffer che con-COMUNICARE CON RECS 101: cedura IOMonitor che si occupa di terà il comando utilizzando la costanteL’INTERFACCIA SOCKET IN C monitorare lo stato delle porte di Input IOGet, che definita altrove, è uguale aSi riporta, di seguito, un esempio di e di Output di RECS 101. 0x75 che rappresenta il codice esade-codice sorgente scritto nel linguaggio Per poter gestire tale operazione cimale del comando Monitor StatoC, il quale rappresenta l’implementa- occorre per prima cosa definire due I/O.zione di un’interfaccia socket basata buffer rispettivamente commandBuf A questo punto utilizzando l’istruzionesulle API dei socket di Berkely. I fram- che conterrà il codice relativo al sendto s’invia l’istruzione Monitormenti di codice riportati di seguito, si comando da inviare a RECS 101 e Stato I/O a RECS 101, inviando comeoccupano di gestire rispettivamente il ResponseBuf che conterrà il valore parametri il valore del buffer e altre“Monitor Stato I/O “ e il “Controllo letto nella porta di I/O. Occorrerà inol- informazioni riguardanti l’indirizzo IPdell’Output” descritti precedentemen- tre definire delle variabili di ausilio di RECS 101.te. quali: Poiché la funzione sendto restituiscePrendendo spunto da questi esempi un valore che è uguale a -1 in casol’utente oltre a capire i meccanismi di • commandLen: è un intero che con- d’errore, al verificarsi di quest’eventofunzionamento descritti potrà essere tiene la lunghezza del comando rela- sarà visualizzato un opportuno mes-capace di costruire una propria inter- tivo a commandBuf. saggio d’errore indicante un problemafaccia personalizzata che funzionerà riscontrato durante la comunicazionecome applicazione, ovvero permetterà • lenReceived: intero che conterrà la con il dispositivo.di gestire RECS 101 attraverso il proto- lunghezza del buffer di ricezione Inviato il comando Monitor Stato I/Ocollo TCP/IP ma senza il supporto di ResponseBuf. bisogna predisporre l’interfaccia socketun Web Browser. a ricevere le informazioni che scaturi-Un’applicazione di questo tipo pote- • i: variabile intera da utilizzare per i scono dall’interrogazione fatta. cicli iterativi. Per prima cosa bisogna allocare i buffer di ricezione ResponseBuf, dopodiché2 bytes 2 bytes 60 bytes mediante l’istruzione recvfrom (che è laStato della porta di Input Stato della porta d’Output Dati non utilizzati corrispondente dell’istruzione sendto nel caso della ricezione) si riceverannoTabella 4: Formato del pacchetto ricevuto dall’interfaccia socket.70 AUTOMAZIONE

AUTOMAZIONETipo Numero di Bytes la parola relativa alla porta diComando di controllo della porta d’Output Output. 12 3 La prima operazione da svolgere è quella di richiedere quale bit all’in- 0x76 Stato della porta di Output terno della parole che compone la porta di Output si vuole modificare.Tabella 5: Formato del commando di controllo della porta di OutputComando di controllo della porta d’Output MSB Porta Output LSB Porta Output 0x76 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 1 0 0 0 0 0 0 0 0 00 0 0 1 1 1 0 0x00 0x0F 1 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 000000000000111 0000|0000|0010|1111 = 0x000F Stato della porta d’outputTabella 6: Esempio di modifica dello stato della porta d’uscita di RECS 101le informazioni relative allo stato della l’istruzione Output Set Command. Tale valore è quindi memorizzatoporta di I/O di RECS 101. Poiché l’istru- • outbit: è un intero inizializzato al nella variabile outbit. Richiamiamozione recvform restituisce un valore la procedura IOMonitor() per legge-uguale a -1, in caso d’errore, è possibi- valore zero che conterrà la posi- re lo stato della porta di I/O chele implementare delle istruzioni che zione del bit della porta di Output verrà memorizzato all’interno del-avvertano nel caso in cui ci siano stati che si vuole modificare. l’array IOStatus.degli errori di comunicazione. • outdata: è un intero inizializzato Da notare che IOStatus [2] conterràSupponendo che non ci sono stati al valore 0x0001 che viene utiliz- la parte MSB della porta di Output eerrori durante la comunicazione, si può zato come maschera per la modi- IOStatus [3] conterrà la parte LSB.passare alla visualizzazione dello stato fica del singolo bit che componedelle porte di I/O mediante la letturadel buffer di ricezione Response Buf.La procedura può terminare chiudendoil Socket TCP e rilasciando le locazioni dimemoria allocate per la gestione deibuffer (vedi listato 1) Il secondo esem-pio che si riporta serve a variare lo statodella porta di Otuput di RECS 101.In particolare si riporta come esempiola procedura per modificare un solo bitdella porta di Output che una voltaselezionato verrà portato a livello logi-co alto. Per tale scopo adopereremo laprocedura SetOutput(). Come nelcaso precedente iniziamo con ledichiarazioni delle variabili locali:• commandBuf: è un array di carat- Figura 5: Esempio che illustra l’algoritmo per settare a livello logico “alto” il 5° bit della porta di Output di RECS 101 teri che conterrà i tre byte che compongono il comando Output Set Command.• commandLen: è un intero che contiene la lunghezza in byte del- AUTOMAZIONE 71

AUTOMAZIONEA questo punto occorre ristabilire una LISTATO 1connessione con RECS 101 pertanto //-------------------------------------------reinizializziamo il Socket tramite la // RECS 101: Esempio di programmazione diprocedura TCPSocketInit(). Poiché in // un interfaccia socket in CC quando si definisce una variabile di // Procedura IOMonitortipo int questa viene allocata all’inter- // By Intellisystem Technologiesno di una cella di memoria di 16 bit // http://www.intellisystem.itsia IOStatus [2] che IOStatus [3] saran- //-------------------------------------------no contenuti in due celle da 16 bit. void IOMonitor()Occorre quindi fare in modo che que-ste siano compattate come unico {valore a 16 bit, tale operazione viene char commandBuf, *ResponseBuf ;svolta eseguendo l’operazione logica int commandLen, lenReceived ;sui bit di IOStatus [2] e IOStauts [3]: int i ;outdata=(Shift di 8 posizioni verso // Inizializzazione del Socket TCPsinistra di IOStatus[2]) OR (IOStatus TCPSocketInit() ;[3]) // Esegui I comandi TCPQuanto appena detto viene espleta- commandBuf = IOGet ;to da un unica istruzione riportata commandLen = 1 ;nel listato: // Invia I comandi a RECS 101outdata|=((IOStatus[2]<<8) | err = sendto (sock,&commandBuf,commandLen,0,IOStatus[3]); (struct sockaddr*)&clientAddr,sizeof(clientAddr));Essendo il nostro obiettivo portare a if (err == -1)livello logico alto solamente il bit sele-zionato tramite la variabile outbit, l’o- {perazione necessaria da fare è quella perror(\"\n Errore nell’invio dei dati !! \n\");di utilizzare la variabile outdata prece- exit (1);dentemente inizializzata ad 1 e farlashiftare (a livello di bit) di tante posi- }zioni verso la sinistra rispetto al valoredi outdata, in questo modo il bit posto // Allocazione di un buffer per I pacchettiinizialmente uguale ad i in outdata si // in ingresso, 1 pacchetto = 16 bytesposizionerà alla relativa posizione ResponseBuf = calloc(0x10, sizeof(char)) ;lasciando tutti gli altri bit uguali a zero.Quanto detto si riassume nella // Ricezione dei pacchetti entrantiseguente pseudo istruzione: lenReceived = recvfrom (sock,ResponseBuf,0x10,0,outdata= outdata OR (1 Shift di out- (struct sockaddr*)&clientAddr,&clientLen);bit posizioni verso sinistra) if (lenReceived < 0) {Che si traduce nella seguente istru-zione C: perror(\"\n Errore nella ricezione dei dati??? \n\") ; exit(0) ;outdata |= (int) (1 << outbit); }A questo punto la variabile outdataconterrà il nuovo valore dello stato // Visualizza la dimensione dei pacchetti entrantidella porta di Out con il bit seleziona- printf(\"\n%d N. di bytes ricevuti -> \n\", lenReceived);to portato a livello logico alto. Occorre // Memorizza lo stato delle porte di I/O // per usi futuri nell’array IOStatus for (i=0; i<4; i++) IOStatus[i] = ResponseBuf[i]; // Visualizza lo stato delle porte di I/O printf(\"\n\n* Stato delle porte di I/O di RECS 101 *\n\") ; printf(\"Porta di Input : %x:%x\t\t Porta di Output : %x:%x\", IOStatus[0], IOStatus[1], IOStatus[2], IOStatus[3]) ; printf(\"***** Intellisystem Technologies *****\n\") ; // Rilascia le allocazioni di memoria allocate per il buffer free(ResponseBuf) ; // Chiude il Socket TCP TCPSocketClose() ; }72 AUTOMAZIONE

AUTOMAZIONEadesso prepararsi per eseguire il com- LISTATO 2mando Output Set Command. Perfare ciò dobbiamo riempire il buffer //-------------------------------------------commandBuf di tre byte rispettiva- // RECS 101: Esempio di programmazione dimente, uno per il codice istruzione // un interfaccia socket in C0x76 e i rimanenti che conterranno la // Procedura SetOutputparte MSB e LSB del nuovo stato della // By Intellisystem Technologiesporta di Output. Adoperando le // http://www.intellisystem.itseguenti istruzioni: //------------------------------------------- void SetOutput ()IOStatus[2]=(outdata&0xff00)>> 8; {IOStatus[3] = (outdata & 0x00ff) ; char commandBuf[3] ;Facciamo in modo che IOStatus [2] int commandLen ;contenga la parte MSB del nuovo int outbit=0, outdata=0x0000 ;stato della porta di Output, il ché si int err ;ottiene eseguendo la seguente ope-razione logica sui bit di outdata: // Richiede quale bit si vuole portare a livello logico // alto della porta di OutputIOStatus[2]= Shift di 8 posizioni verso destra printf(\" Prego selezionare il bit della porta d’Output(outdata AND 11111111|00000000) di cui si vuole invertire lo stato logico “alto”(0-15) :\"); scanf(\"%d\", &outbit) ;Per il secondo caso sarà sufficienteeseguire solamente la seguente ope- // Legge lo stato corrente delle porte di I/Orazione logica sui bit di outdata: IOMonitor() ;IOStatus[3]= outdata AND // Re-Initializza il Socket TCP11111111|00000000 TCPSocketInit() ;Riempito il buffer che conterrà il // Determina il nuovo valore della porta d’Output a partirecomando da inviare a RECS 101, non // dallo stato attuale delle usciteci rimane che adoperare l’istruzione outdata = ((IOStatus[2]<<8) | IOStatus[3]) ;sendto per rendere tale comando ope- outdata |= (int) (1 << outbit);rativo. // Or operation with currentle selected BitSi ricorda che tale istruzione restituisce // Memorizza il nuovo stato della porta di Outputun valore che nel caso sia -1 indica che IOStatus[2] = (outdata & 0xff00)>> 8 ;l’informazione non è stata trasmessa IOStatus[3] = (outdata & 0x00ff) ;correttamente.Per concludere, l’ultima operazione da // Costruisci il buffer che conterrà Il comandofare è quella di chiudere il socket // Output Set Commandmediante la chiamata alla procedura // 1) Command ID IOSet=0x76TCPSocketClose.(vedi listato 2) commandBuf[0] = IOSet ;Per maggiore chiarezza la figura 5 // 2) Output status setriporta un esempio pratico di quanto commandBuf[1] = (BYTE) ((outdata & 0xff00) >> 8) ;descritto precedentemente, pertanto commandBuf[2] = (BYTE) (outdata & 0x00ff) ;si supporrà quanto segue: commandLen = 3 ;• Lo stato della porta di Output di // Invia I comandi a RECS 101 RECS 101 è uguale a err = sendto (sock,&commandBuf,commandLen,0, 00000000|10001001. (struct sockaddr*)&clientAddr,sizeof(clientAddr)) ;• Si vuole portare a livello logico “alto” if (err == -1 ) { perror(\"\n Errore nell’invio dei dati !! \n\"); exit (1); } // Chiude il Socket TCP TCPSocketClose() ; } AUTOMAZIONE 73

AUTOMAZIONELISTATO 3 il quinto bit della porta di Output a partire dalla destra.//------------------------------------------// RECS 101: Esempio di programmazione di un interfaccia COMUNICARE CON RECS 101:// socket in Java L’INTERFACCIA SOCKET IN// Procedura readIOport JAVA// By Intellisystem Technologies Come detto in precedenza per supera-//------------------------------------------ re tutte le limitazioni dovute alla gestione di RECS 101 mediante unpublic int readIOport() software applicativo la soluzione pro-{ posta da Intellisystem Technologies utilizza la tecnologia Java che prevede Socket socketTCP = null; la creazione di un’Applet di controllo, int tmp = 0; gestita mediante un interfaccia brow- int inputData = 0; ser. Come ben noto, le Applet sono dei byte rxData[] = new byte[16]; programmi autonomi, scritti in Java, byte data[] = {COMMAND_GET}; eseguibili mediante un comune brow- ser. La potenzialità di un software scrit- try { to in Java, consente di essere totalmen- socketTCP=new Socket(InetAddress.getByName(m_host), m_port); te indipendenti dalla piattaforma HW socketTCP.setTcpNoDelay(true); su cui si esegue l’applicazione. Senza socketTCP.getOutputStream().write(data, 0, data.length); entrare troppo nei dettagli della pro- instream=new DataInputStream(socketTCP.getInputStream()); grammazione in Java riportiamo di tmp = instream.read(rxData, 0, rxData.length); seguito un frammento di codice Java if (tmp != -1) riguardante un esempio d’implemen- { tazione dell’interfaccia socket basata inputData = (int) (rxData[2] << 8 | (rxData[3] & 0x00ff)); su Applet che permette la ricezione e inputData &= 0xffff; trasmissione di degnali di I/O, attraver- } so il protocollo TCP. Il lettore più atten- socketTCP.close(); to può paragonare i codici seguenti instream.close(); con quelli scritti in C ed evidenziare } quindi le analogie in termini di funzio- nalità. (listato 3) catch (Exception e) { BIBLIOGRAFIA System.out.println(\"Err : \" + e); } [1]Introduzione allo stack TCP/ IP,IntellisystemTechnologie, return inputData; http://www.intellisystem.it/} download.htm//------------------------------------------- [2]Netid Managed Services,// Procedura writeOutputPort Information technology,//------------------------------------------- Northwestern Technology, http://gradeswww.acns.nwpublic void writeOutputPort(int outdata) u.edu/ist/snap/doc/snif-{ fing.html. Socket socketTCP = null; [3]Internet spoofing reference byte[] data = new byte[4]; page, http:// www.brd.ie / data[0] = COMMAND_SET; paper/ sslpaper / hyper- data[1] = (byte) ((outdata >> 8) & 0x000000ff); lin.html. data[2] = (byte) (outdata & 0x000000ff); // Initialize socket Electronic shop 16 try { socketTCP=new Socket(InetAddress.getByName(m_host), m_port); socketTCP.setTcpNoDelay(trujhe); socketTCP.getOutputStream().write(data, 0, data.length); socketTCP.close(); } catch (Exception e) { System.out.println(\"Err: \" + e); }}74 AUTOMAZIONE