Problema gestione stringhe con Ethernet

Sto cercando di realizzare una sorta di parser XML su connessione TCP, ma mi capita una cosa strana…

Mi son fatto una funzione che cerca uno specifico TAG all’interno di una stringa XML, e se lo faccio girare da solo funziona correttamente, ma se poi lo metto all’interno di una gestione in loop della connessione TCP, continua a funzionare, ma mi sballa completamente la dimensione della stringa trovata, aggiungendo 4 caratteri alla fine che non hanno senso.

La cosa strana è k lo fa in maniera fissa, ovvero sempre 4 caratteri indipendentemente dalla lunghezza del TAG, ma lo fa solo se uso le funzioni TCP…

Posto il codice :


#include <Ethernet.h>
#include <stdio.h>
#include <String.h>

char inTCPBuffer[255]; // Stringa per la gestione dei messaggi in arrivo

// Dati per la gestione della rete
byte mac = { 222, 173, 190, 239, 254, 237 };
byte ip = { 10, 0, 0, 177 };
byte gateway = { 10, 0, 0, 1 };
byte subnet = { 255, 255, 0, 0 };
int port = 23;
Server server(port); // Instanzio il server

byte endByte = 0; // Carattere finale della trasmissione TCP

void setup(){
Ethernet.begin(mac, ip, gateway, subnet);
server.begin();
// Avvio la seriale di debug
Serial.begin(9600);
Serial.println(“AVVIO”);
}

void loop(){

Client client = server.available();
if (client) {
int indicebuffer = 0; // Contatore dei caratteri in ingresso
if (client.connected() && client.available()) {
while (inTCPBuffer[indicebuffer-1] != endByte) {
if (indicebuffer<255) inTCPBuffer[indicebuffer] = client.read(); // Riempo il buffer in ingresso
indicebuffer++;
}
parse_command(inTCPBuffer, “cmd=”"); // Lancio la fuznione alla ricerca di un TAG specifico
}
}

//parse_command("<data cmd=“Ciao”>", “cmd=”"); // Lancio la fuznione alla ricerca di un TAG specifico
}

void parse_command(char* XML, char* TAG){
int dim = 0; //strlen(TAG);
char ptr = strstr(XML, TAG);
ptr = strstr(ptr, “”");
for(int i=1;i<=strlen(ptr);i++){
if(ptr
==’"’){*

  • // Se trovo il carattere di chiusura TAG esco dal ciclo for*

  • break;*

  • }else{*

  • dim++; // Incremento la dimensione della variabile che conterrà il TAG*

  • }*

  • }*

  • char string_1[dim]; // Dimensiono la stringa che contiene il valore del TAG in base a dim*

  • // Stanmpo la lunghezza della stringa appena generata*

  • Serial.print("Dimensiono la stringa a : ");*

  • Serial.print(dim);*

  • Serial.println(" caratteri");*

  • for(int i=0;i<=sizeof(string_1)-1;i++){*
    string_1 = ptr[i+1]; // Copio nella stringa i singolo caratteri del TAG trovato
    * }*
    * // Stanmpo la lunghezza della stringa dopo aver copiato i caratteri*
    * Serial.print("Lunghezza Stringa : ");*
    * Serial.println(strlen(string_1));*

* Serial.print("Valore del TAG trovato : ");*
* Serial.println(string_1);*

}
*****************
Se mi collego tramite TCP e invio la stringa

Questo produce un OUTPUT del genere
Dimensiono la stringa a : 4 caratteri
Lunghezza Stringa : 8
Valore del TAG trovato : Ciaoì
ç
Se modifico lo script nella parte Loop, escludendo la gestione del TCP e forzando manualmente il parser in questo modo :
void loop(){
* parse_command("<data cmd=“Ciao”>", “cmd=”"); //
_
}*_
L’OUTPUT diventa questo :
Valore del TAG trovato : Ciaoh
Dimensiono la stringa a : 4 caratteri
Lunghezza Stringa : 5
Ci sto perdendo le ore, e non riesco a venirne a capo… se qualcuno ha delle idee di come risolvere il problema, sono ben accette…

Ciao

stai usando la libreria String di wiring?

Vedo uno String.h con la S maiuscola..

Cerca di usare solo le stringhe del C con buffer fissi pre allocati.. cioè allocati un bel buffer da 512 byte all'inizio e lavora sempre dentro a quello...

Allocare dinamicamente le stringhe non so quanto affidabile sia..inoltre il processore ha poca ram, meglio pre-allocare.

Parsare XML in arduino è un po masochistico, di solito io uso un servizio web parsa gli XML e me li passa in un formato binario.

(tipo quello che usa flash per remotare)

m

Ciao Massimo, speravo tanto in un tuo intervento ;)

Non sto usando le librerie di wiring perchè come ti avevo detto al cosro, fanno un casino immane e inchiodano tutto.. ho cercato di lavorare solo con le stringhe C proprio per risolvere questo problema..

Ora non si inchioda più ma continua ad aggioungermi dei caratteri a caso alla fine, anche se il dimensionamento della variabile lo fa correttamente..

La cosa molto strana è che come ho scritto lo fa solo quando è nel ciclo del client TCP... assurdo !!!

Ho provato a pre-allocare lo spazio, ma mi va in conflitto con la funzione "strstr" che mi serve per trovare il tag che cerco nella stringa...

So che forse è uno spreco usare XML in arduino, ma sto proprio cercando di realizzare uno script interfacciabile direttamente con FLASH e il suo socket XML senza passare da seriale o vari sw. proxy...

Hai idee ?

Ciao

la socket XML di flash non ha bisogno di XML :) se usi AS2 ed XMLSocket devi solo mettere uno \0 alla fine del messaggio da inviare (o quando da arduino mandi a flash) con AS3 puoi usare anche solo Socket

per il resto puoi usare un formato piu stringato.

se usi arduino solo per manipolare pins, leggere ingressi analogici e simili puoi usare queste api:

http://code.google.com/p/as3glue/

installi standard firmata sull'arduino e con questa libreria dentro actionscript puoi scrivere cose del tipo arduino.analogRead(0) e lui recupera in automatico dall'arduino il valore dell'ingresso analogico 0

m

E' vero potrei risparmiarmi l'XML tanto il socket funziona lo stesso se usi \0 alla fine, ma volevo fare una cosa un po + standard diciamo.. tanto x complicarsi la vita.. ;)

Ho visto il link che hai postato.. in effetti volevo raggiungere una cosa simile, ma nativamente su TCP e non seriale...

Ho trovato anche un bell'esempio di comando utilizzando il protocollo OSC ma anche questo passa via seriale...

E dire che mi basta poco per sbloccare sta situazione... non capisco solo perchè metta quei caratteri a caso che mi impediscono di confrontare le stringhe di comando che gli mando...

Mi sembra strano che sia capitato solo a me sto problema... forse sbaglio qualcosa, ma perchè se non uso la TCP mi funziona ????

Hai percaso delle librerie che non siano quelle di Wiring che lavorino sulle stringhe ?

Grazie

Marco

mmmmm cerca cerca e mo provo questo :

http://tinkerit.googlecode.com/files/eth_Firmata_v1.pde

Sembra quasi di conoscere chi l'ha fatto ;) ;) ;) ;) ;)

attenzione che quella versione è un po antica

potrebbe non funzionare con l'ultimo as3glue

fammi sapere

m

Si ora cerco di capire come funge, grazie ancora

M

Allora, ho lasciato perdere la libreria che mi hai suggerito perchè troppo complessa rispetto a quello che devo fare io..

Alla fine ho scoperto che se dimensiono la variabile in manoera fissa (tenendomi un pelo largo) e la setto con il comando

int buffer_tmp = 128; memset(string_1,'\0',buffer_tmp);

Me la riempe di valori null, per cui quando gli scrivo dentro dal 1 al N carattere e poi verifico quanto è lunga, mi da il valore giusto non considerandomi i caratteri a caso che sparava prima...

Non so se è corretta come procedura ma ora almeno sembra funzionare.

Grazie

Marco