2013-02-04 5 views
16

Sono in grado di impostare l'RTS con ioctl in una piccola app Terminal, ma non nel mio codice plugin Mac, sebbene entrambi eseguano lo stesso codice. Nel plugin posso solo "ottenere" i flag/pin delle porte seriali, ma non "impostarli". Nell'app Terminal posso sia "get" che "impostarli" .Vedo un errore di ENODEV Il numero di errore è 19 e il messaggio è "Operazione non supportata dal dispositivo."Come posso impostare l'RTS con ioctl() in un plug-in per Mac?

Se questo è un problema di sicurezza (essendo nel contesto di un browser) c'è un modo per ottenere il permesso di modificare il flag con ioctl? Ho un dispositivo seriale collegato a una porta USB. Sto usando il driver FTDI vcp (porta virtuale com). .. lato Btw, ottengo lo stesso risultato utilizzando sia Safari e Firefox Qui di seguito è il mio codice:

int disableRTS() 
{ 
    char fd, ret, flags; 

    // open device 
    if ((fd = open("/dev/cu.mydevice", O_RDWR | O_NDELAY)) < 0) 
    { 
     fprintf(stderr, "failed to open device"); 
     return -1; 
    } 

    // Get the current state of the bits 
    ioctl(fd, TIOCMGET, &flags); 
    fprintf(stderr, "Flags are %x.\n", flags);  

    flags &= ~TIOCM_RTS; // Disable the RTS bit 
    ret = ioctl(fd, TIOCMSET, &flags); 

    if (ret == -1) 
     fprintf(stderr, "TIOCMSET failed\n"); 
    else 
     fprintf(stderr, "TIOCMSET succeeded. flags: %x.\n", flags); 

    return 0; 
} 

=========

Aggiornamento

Se aggiorno la pagina del browser, forzando il codice a essere eseguito nuovamente, ioctl() restituisce 0, che indica il successo. Sfortunatamente, ho bisogno che funzioni per la prima volta. Anche se scrivo un loop e faccio una pausa momentanea, usando il metodo usleep(), e faccio dei tentativi successivi, fallisce. Ma poi, quando lo aggiorno, succede. Ho anche duplicato il problema in un secondo progetto esclusivamente NPAPI "BasicPlugin.xcodeproj", fornito da Mozilla. Il mio primo progetto di plugin è un progetto di Firebreath. Inizialmente falliscono entrambi, quindi riescono a ricaricare la pagina. Ho anche 2 app Mac separate che funzionano correttamente. Uno è SerialTools, e usa lo stesso identico metodo per impostare l'RTS su (e DTR off) come l'app del mio terminale e i plugin.

========

Update 2

Sono stato in grado di ottenere a livello di codice di supporto di Apple su questo, quindi una soluzione può essere venuta. L'ingegnere ha detto che è "bizzarro" che il codice gira in modo diverso in un plug-in che all'esterno di uno, e sta parlando con gli ingegneri del plugin di Safari.

+0

Modificare il caso di errore 'fprintf' in una chiamata a' perror ("TIOCMSET") 'e vedere cosa dice l'errore. –

+0

Mi dispiace, ho dimenticato di dirlo. Il messaggio di errore è "Operazione non supportata dal dispositivo". Il suo numero di errore è 19. ENODEV. – Alyoshak

+0

Per quanto riguarda la munizione che sta per scadere senza una risposta corretta, non so cosa fare. Credo che lo perderò anche se un ingegnere Apple ha accettato questo problema e sta cercando di trovare una soluzione. Ha detto che è "bizzarro" che il codice del plugin funzioni in modo diverso rispetto al codice non-plugin. Almeno sarò in grado di aggiungere una risposta corretta per qualsiasi cosa possa aiutare. – Alyoshak

risposta

1

La risposta è che ogni volta che TIOCMSET o TIOCMGET sono utilizzati in una chiamata a ioctl() il 3 ° parametro deve essere un int. Stavo usando un char. Duh. Non posso credere di aver perso questo. TIOCMSET e TIOCMGET sono definiti come segue:

#define TIOCMSET _IOW('t', 109, int) /* set all modem bits */ 
    … 
    #define TIOCMGET _IOR('t', 106, int) /* get all modem bits */ 

e quindi non è difficile immaginare che l'utilizzo di un char come tipo per il mio "bandiere" var potrebbe causare comportamenti imprevedibili.

1

È possibile creare un plug-in AppleScript, che verrà eseguito automaticamente in determinati orari o durante l'accesso o in background.

AppleScript può eseguire il codice terminale. Così puoi facilmente far girare automaticamente il codice get/set che stai correntemente correndo nel Terminale.

Il codice per il plugin AppleScript sarà qualcosa di simile ::

tell application "Finder" 
    display dialog explanation buttons {"GET", "SET"} default button "GET" 
    if result = {button returned:"GET"} then 
     tell application "Terminal" 
       set status to (do shell script "terminal code for getting the RTS here") 
      end tell 
    else if result = {button returned:"SET"} then 
      tell application "Terminal" 
       set status to (do shell script "terminal code for setting the RTS here") 
      end tell 
    end if 
end tell 
Problemi correlati