2011-05-24

Comando remoto via WEB per Emtec s800h - 3/3

Prosegue la realizzazione del prototipo di comando via WEB per il mio EMTEC Movie Cube s800h iniziato con il primo post e proseguito con il secondo post.
Per effettuare le modifiche al sistema è necessario connettersi tramite telnet all'indirizzo del proprio dispositivo s800h, effettuare il login con il nome utente root e non verrà richiesta la password.
Come già accennato, in base ad indicazioni trovate in altri blog, va modificato un file di sistema che si occupa dell'attivazione del programma centrale all'avvio del dispositivo, il file in questione è /usr/local/etc/rcS ed intorno alla riga 25 vanno aggiunte due righe:


rm /tmp/commands.txt
touch /tmp/commands.txt
il primo comando rimuove un'eventuale file già esistente ed il secondo ne crea uno nuovo vuoto. Poi, segue un'istruzione if che va lasciata inalterata ed al suo interno ci sono due modi in cui viene invocato il programma centrale e queste due righe vanno modificate in modo da precedere l'invocazione normale con
tail -f /tmp/commands.txt |
il risultato finale della sola parte modificata sarà il seguente:
if [ -f $DEFAULT_AP_DIR/DvdPlayer ] && [ -x $DEFAULT_AP_DIR/DvdPlayer ]; then
        cd $DEFAULT_AP_DIR                                               
        rm /tmp/commands.txt                                       
        touch /tmp/commands.txt                                    
        if [ -f $DEFAULT_AP_DIR/RootApp ] && [ -x $DEFAULT_AP_DIR/RootApp ]; then
                echo Running dvdplayer with RootApp                          
                tail -f /tmp/commands.txt | ./RootApp DvdPlayer&       
        else                                                                 
                echo Running dvdplayer                                       
                tail -f /tmp/commands.txt | ./DvdPlayer&               
        fi                                                                   
else                                                                         
        /etc/dvdplayer/script/run_tail                                       
fi                                                                              
Se la versione attuale differisce molto da quello che ho riportato astenetevi dal fare modifiche, penso che possa dipendere da versioni differenti di firmware e potreste correre qualche rischio di troppo, al limite chiedetemi un parere.
Questa modifica non cambierà nessun comportamento visibile nel dispositivo, ma per provare se ha avuto effetto potete riavviare il dispositivo e provare ad impartire qualche comando direttamente dalla shell, ad esempio
echo X >/tmp/commands.txt
per simulare la freccia verso il basso e se nell'interfaccia vedrete selezionare la voce seguente del menu pricipale avrà funzionato.
Adesso è il momento di inserire la pagina html, l'immagine e lo script cgi per alimentare l'interfaccia WEB.
L'immagine potete prelevare quella che ho inserito nel primo post, il contenuto del file html che ho utilizzato è il seguente, potreste non vedere correttamente tutte le righe, selezionandole dovrebbe essere possibile copiarle:
<HTML>
<HEAD>
<script language="JavaScript">
var xmlHttp;
function createXMLHttpRequest()
{
    if (window.ActiveXObject)
    {
        xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
    }
    else if (window.XMLHttpRequest)
    {
        xmlHttp = new XMLHttpRequest();
    }
}
function sendCmd(cmd)
{
        var url = "/cgi-bin/tc.cgi?"+cmd;
        createXMLHttpRequest();
        xmlHttp.open("GET", url, true);
        xmlHttp.setRequestHeader("If-Modified-Since", "0");
        xmlHttp.send(null);
        return false;
}
</script>
</HEAD>
<BODY>
<img src="../tc.png" width="200" height="644" border="0" usemap="#map" />
<map name="map">
<area shape="circle" coords="44,47,18" href="?mute" href="?mute" onclick="sendCmd('mute');return false;"/>
<area shape="circle" coords="165,50,18" href="?off" href="?off" onclick="sendCmd('off');return false;"/>
<area shape="rect" coords="145,74,183,101" href="?pref" onclick="sendCmd('pref');return false;"/>
<area shape="rect" coords="106,74,142,101" href="?tvsys" onclick="sendCmd('tvsys');return false;"/>
<area shape="rect" coords="65,74,102,101" href="?setup" onclick="sendCmd('setup');return false;"/>
<area shape="rect" coords="26,74,62,99" href="?option" onclick="sendCmd('option');return false;"/>
<area shape="rect" coords="26,104,62,127" href="?info" onclick="sendCmd('info');return false;"/>
<area shape="rect" coords="65,105,102,128" href="?search" onclick="sendCmd('search');return false;"/>
<area shape="rect" coords="107,105,143,128" href="?zoom" onclick="sendCmd('zoom');return false;"/>
<area shape="rect" coords="145,105,181,128" href="?audio" onclick="sendCmd('audio');return false;"/>
<area shape="circle" coords="168,154,19" href="?return" onclick="sendCmd('return');return false;"/>
<area shape="circle" coords="40,153,18" href="?home" onclick="sendCmd('home');return false;"/>
<area shape="poly" coords="87,193,66,171,87,158,122,158,142,172,122,193,88,193" href="?up" onclick="sendCmd('up');return false;"/>
<area shape="poly" coords="81,197,81,234,60,251,46,226,46,198,60,175" href="?left" onclick="sendCmd('left');return false;"/>
<area shape="poly" coords="125,196,146,177,160,195,160,228,147,252,126,234" href="?right" onclick="sendCmd('right');return false;"/>
<area shape="circle" coords="103,214,22" href="?ok" onclick="sendCmd('ok');return false;"/>
<area shape="poly" coords="84,236,123,236,143,258,124,271,83,271,65,255" href="?down" onclick="sendCmd('down');return false;"/>
<area shape="poly" coords="132,278,163,248,188,248,187,298,132,298" href="?volup" href="?up" onclick="sendCmd('volup');return false;"/>
<area shape="poly" coords="20,252,20,295,69,296,70,279,40,251" href="?voldown" href="?up" onclick="sendCmd('voldown');return false;"/>
<area shape="rect" coords="22,303,71,328" href="?1" onclick="sendCmd('1');return false;"/>
<area shape="rect" coords="79,302,128,327" href="?2" onclick="sendCmd('2');return false;"/>
<area shape="rect" coords="133,302,181,328" href="?3" onclick="sendCmd('3');return false;"/>
<area shape="rect" coords="23,334,72,358" href="?4" onclick="sendCmd('4');return false;"/>
<area shape="rect" coords="78,334,126,357" href="?5" onclick="sendCmd('5');return false;"/>
<area shape="rect" coords="134,335,181,357" href="?6" onclick="sendCmd('6');return false;"/>
<area shape="rect" coords="24,365,70,388" href="?7" onclick="sendCmd('7');return false;"/>
<area shape="rect" coords="78,365,127,388" href="?8" onclick="sendCmd('8');return false;"/>
<area shape="rect" coords="133,365,183,389" href="?9" onclick="sendCmd('9');return false;"/>
<area shape="rect" coords="23,394,71,417" href="?question" onclick="sendCmd('question');return false;"/>
<area shape="rect" coords="78,395,126,417" href="?0" onclick="sendCmd('0');return false;"/>
<area shape="rect" coords="133,396,181,419" href="?eject" onclick="sendCmd('eject');return false;"/>
<area shape="rect" coords="16,435,63,460" href="?pause" onclick="sendCmd('pause');return false;"/>
<area shape="rect" coords="66,431,140,463" href="?play" onclick="sendCmd('play');return false;"/>
<area shape="rect" coords="142,430,193,463" href="?stop" onclick="sendCmd('stop');return false;"/>
<area shape="rect" coords="16,463,62,486" href="?rew" onclick="sendCmd('rew');return false;"/>
<area shape="rect" coords="64,463,102,486" href="?fwd" onclick="sendCmd('fwd');return false;"/>
<area shape="rect" coords="103,464,143,485" href="?prev" onclick="sendCmd('prev');return false;"/>
<area shape="rect" coords="142,463,184,487" href="?next" onclick="sendCmd('next');return false;"/>
<area shape="rect" coords="19,489,62,515" href="?ab" onclick="sendCmd('ab');return false;"/>
<area shape="rect" coords="64,490,102,515" href="?rec" onclick="sendCmd('rec');return false;"/>
<area shape="rect" coords="103,490,143,515" href="?frame" onclick="sendCmd('frame');return false;"/>
<area shape="rect" coords="143,490,183,515" href="?sub" onclick="sendCmd('sub');return false;"/>
<area shape="rect" coords="20,518,61,544" href="?ts" onclick="sendCmd('ts');return false;"/>
<area shape="rect" coords="63,518,100,544" href="?copy" onclick="sendCmd('copy');return false;"/>
<area shape="rect" coords="102,518,143,545" href="?select" onclick="sendCmd('select');return false;"/>
<area shape="rect" coords="144,519,183,544" href="?repeat" onclick="sendCmd('repeat');return false;"/>
<area shape="rect" coords="19,547,61,571" href="?red" onclick="sendCmd('red');return false;"/>
<area shape="rect" coords="63,545,101,571" href="?green" onclick="sendCmd('green');return false;"/>
<area shape="rect" coords="103,544,143,571" href="?yellow" onclick="sendCmd('yellow');return false;"/>
<area shape="rect" coords="145,544,184,571" href="?blue" onclick="sendCmd('blue');return false;"/>
</map/>                                    
<area shape="rect" coords="16,463,62,486" href="?rew" onclick="sendCmd('rew');return false;"/>                                        
<area shape="rect" coords="64,463,102,486" href="?fwd" onclick="sendCmd('fwd');return false;"/>                                       
<area shape="rect" coords="103,464,143,485" href="?prev" onclick="sendCmd('prev');return false;"/>                                    
<area shape="rect" coords="142,463,184,487" href="?next" onclick="sendCmd('next');return false;"/>                                    
<area shape="rect" coords="19,489,62,515" href="?ab" onclick="sendCmd('ab');return false;"/>                                          
<area shape="rect" coords="64,490,102,515" href="?rec" onclick="sendCmd('rec');return false;"/>                                       
<area shape="rect" coords="103,490,143,515" href="?frame" onclick="sendCmd('frame');return false;"/>                                  
<area shape="rect" coords="143,490,183,515" href="?sub" onclick="sendCmd('sub');return false;"/>                                      
<area shape="rect" coords="20,518,61,544" href="?ts" onclick="sendCmd('ts');return false;"/>                                          
<area shape="rect" coords="63,518,100,544" href="?copy" onclick="sendCmd('copy');return false;"/>                                     
<area shape="rect" coords="102,518,143,545" href="?select" onclick="sendCmd('select');return false;"/>                                
<area shape="rect" coords="144,519,183,544" href="?repeat" onclick="sendCmd('repeat');return false;"/>                                
<area shape="rect" coords="19,547,61,571" href="?red" onclick="sendCmd('red');return false;"/>                                        
<area shape="rect" coords="63,545,101,571" href="?green" onclick="sendCmd('green');return false;"/>                                   
<area shape="rect" coords="103,544,143,571" href="?yellow" onclick="sendCmd('yellow');return false;"/>                                
<area shape="rect" coords="145,544,184,571" href="?blue" onclick="sendCmd('blue');return false;"/>                                    
</map>
</BODY>
</HTML>
Lo script cgi che ho realizzato ha il seguente contenuto:
#!/bin/sh
echo "Content-type: text/html"
echo
ST_CMD=`echo $QUERY_STRING | cut '-d&' -f1`
CMD=$ST_CMD
if [ "$CMD" = "0" ] ; then N_CMD="0"
elif [ "$CMD" = "mute" ] ; then N_CMD="m"
elif [ "$CMD" = "off" ] ; then N_CMD="O"
elif [ "$CMD" = "pref" ] ; then N_CMD="{"
elif [ "$CMD" = "tvsys" ] ; then N_CMD="\\"
elif [ "$CMD" = "setup" ] ; then N_CMD="/"
elif [ "$CMD" = "option" ] ; then N_CMD=""
elif [ "$CMD" = "info" ] ; then N_CMD=""
elif [ "$CMD" = "search" ] ; then N_CMD=""
elif [ "$CMD" = "zoom" ] ; then N_CMD="z"
elif [ "$CMD" = "audio" ] ; then N_CMD="a"
elif [ "$CMD" = "return" ] ; then N_CMD=","
elif [ "$CMD" = "home" ] ; then N_CMD="\{"
elif [ "$CMD" = "up" ] ; then N_CMD="W"
elif [ "$CMD" = "left" ] ; then N_CMD="A"
elif [ "$CMD" = "right" ] ; then N_CMD="D"
elif [ "$CMD" = "ok" ] ; then N_CMD=" "
elif [ "$CMD" = "down" ] ; then N_CMD="X"
elif [ "$CMD" = "volup" ] ; then N_CMD="V"
elif [ "$CMD" = "voldown" ] ; then N_CMD="v"
elif [ "$CMD" = "question" ] ; then N_CMD=""
elif [ "$CMD" = "eject" ] ; then N_CMD=""
elif [ "$CMD" = "pause" ] ; then N_CMD="Z"
elif [ "$CMD" = "play" ] ; then N_CMD="S"
elif [ "$CMD" = "stop" ] ; then N_CMD="Q"
elif [ "$CMD" = "rew" ] ; then N_CMD="f"
elif [ "$CMD" = "fwd" ] ; then N_CMD="F"
elif [ "$CMD" = "prev" ] ; then N_CMD="p"
elif [ "$CMD" = "next" ] ; then N_CMD="n"
elif [ "$CMD" = "ab" ] ; then N_CMD="="
elif [ "$CMD" = "rec" ] ; then N_CMD="r"
elif [ "$CMD" = "frame" ] ; then N_CMD=""
elif [ "$CMD" = "sub" ] ; then N_CMD="s"
elif [ "$CMD" = "ts" ] ; then N_CMD=""
elif [ "$CMD" = "copy" ] ; then N_CMD="&"
elif [ "$CMD" = "select" ] ; then N_CMD=""
elif [ "$CMD" = "repeat" ] ; then N_CMD="+"
elif [ "$CMD" = "red" ] ; then N_CMD=""
elif [ "$CMD" = "green" ] ; then N_CMD=""
elif [ "$CMD" = "yellow" ] ; then N_CMD=""
elif [ "$CMD" = "blue" ] ; then N_CMD=""
elif [ "$CMD" -ge "1" -a "$CMD" -le "9" ] ; then N_CMD="$CMD"
else    N_CMD=""
fi
[ -n "$N_CMD" ] && echo "$N_CMD" >>/tmp/commands.txt
cat ../tc.html
I file vanno posizionati nel seguente modo:
  • tc.png nella directory /var/www
  • tc.html nella directory /var/www
  • tc.cgi nella directory /var/www/cgi-bin
Per copiare i file potete copiarli tramite rete nella normale condivisione del dispositivo e poi copiare dalla directory /tmp/hdd/volumes/HDD1 nelle destinazioni che ho indicato.
Il terzo file, tc.cgi va reso eseguibile con
chmod ugo+x /var/www/cgi-bin/tc.cgi
Per provare se il tutto funziona, senza necessità di riavviare aprire con un browser la pagina:
http://<ip_del_vostro_s800h>/cgi-bin/tc.cgi
sostituendo <ip_del_vostro_s800h> con l'indirizzo di rete del dispositivo oppure con il nome di rete con il quale lo raggiungete di solito. Se risponde correttamente dovrebbe essere visualizzata la foto del mio telecomando e cliccando sui tasti dovreste venerne l'effetto sullo schermo della vostra TV. I più attenti avranno notato l'aggiunta di codice JavaScript di cui non avevo accennato nelle spiegazioni precedenti per non appesantire troppo i post, il JavaScript in questione serve per evitare di effettuare il refresh della pagina ogni volta che si preme un tasto, così facendo si velocizza di un po' l'utilizzo.
Se qualcosa non dovesse funzionare fatemi sapere che posso provare a porre rimedio, potrebbe essere dovuto a qualche errore di copiatura o le correzioni dell'ultimo minuto del prototipo. Non tutti i tasti hanno la gestione completa, alcuni comandi non sono riuscito ad associarli correttamente in base alle indicazioni trovate, con il tempo li proverò tutti e li sistemerò.
In seguito proverò a realizzare qualcosa di più elegante e più veloce, magari al posto dello script in shell per il cgi potrei scrivere un programma in C e compilarlo allo stesso modo in cui avevo compilato in passato busybox per lo stesso dispositivo. Inoltre mi piacerebbe realizzare un'applicazione specifica per Android che possa dialogare in modo più diretto con il mio s800h.

Stay tuned!

1 commento: