; DTPS
;
; Programma per Proteus
;
; (C) 2004 Simone Zanella Productions
;
; Riceve dati da un terminale connesso via RS-232 che comunica con il protocollo DTP;
; i dati ricevuti (se la trasmissione ha avuto successo) sono successivamente introdotti in emulazione di
; tastiera - ogni dato è terminato da POSTFIX.
; Questo programma può essere installato come script associato al servizio Proteus.
;
; N.B. Per il corretto funzionamento, questo script richiede:
; - PROTEXT.DLL (DLL di default distribuita con Proteus)
; - DTPCLIENT.DLL (DLL Datalogic®)
; - DTPCMDS.DLL (DLL Datalogic®)
;
; I parametri di configurazione si trovano all'inizio del programma e sono:
; - COMPORT = porta di comunicazione (vedi le costanti mnemoniche sottostanti)
; - COMSPEED = velocità di comunicazione (vedi le costanti mnemoniche sottostanti)
; - POLLINTERVAL = periodicità (in secondi) con la quale il programma verifica la presenza di un terminale
; - TIMEOUT = timeout (in millisecondi) per la risposta di un terminale
; - FILENAME = nome del file da scaricare (percorso completo sul terminale)
; - TEMPFILE = nome del file temporaneo, nel quale ricevere i dati
; - KILLFILE = valore boolean (1 o 0) che indica se il file sul terminale deve essere cancellato dopo la trasmissione
; - QUITAFTERRX = valore boolean (1 o 0) che indica se si deve forzare l'uscita sul DTPS al termine della trasmissione
; - PACE = ritardo dopo l'invio in emulazione di tastiera di ciascuna riga (in secondi);
; - POSTFIX = terminatore
;
; Il codice commentato più sotto permette anche in alternativa di:
; - selezionare una specifica finestra (applicativo Ultra-Edit) ed inviare il dato verbatim, seguito da Invio;
; - lanciare il blocco note (se non aperto), introdurre il dato verbatim (seguito da Invio) e tornare alla finestra
; iniziale.
#!proteus -z -j
!include "win32.prt"
!extern DTPOpenClient, PROTEXT.DLL, ProteusDTPOpenClient, 2, 0
!extern DTPSetFailTimeout, PROTEXT.DLL, ProteusDTPSetFailTimeout, 2, 0
!extern DTPPing, PROTEXT.DLL, ProteusDTPPing, 1, 0
!extern DTPSetAttrib, PROTEXT.DLL, ProteusDTPSetAttrib, 5, 0
!extern DTPFileRx, PROTEXT.DLL, ProteusDTPFileRx, 4, 0
!extern DTPCloseClient, PROTEXT.DLL, ProteusDTPCloseClient, 1, 0
!extern DTPDelete, PROTEXT.DLL, ProteusDTPDelete, 3, 0
!extern DTPExit, PROTEXT.DLL, ProteusDTPExit, 1, 0
!extern DTPChDir, PROTEXT.DLL, ProteusDTPChDir, 2, 0
CONST DTP_DELETE_ALL = 1
CONST DTP_DELETE_SOME = 0
; Porte seriali
CONST DTP_COM1 = 1
CONST DTP_COM2 = 2
CONST DTP_COM3 = 3
CONST DTP_COM4 = 4
; Velocità
CONST DTP_BR_300 = 0
CONST DTP_BR_600 = 1
CONST DTP_BR_1200 = 2
CONST DTP_BR_2400 = 3
CONST DTP_BR_4800 = 4
CONST DTP_BR_9600 = 5
CONST DTP_BR_19200 = 6
CONST DTP_BR_38400 = 7
CONST DTP_BR_57600 = 8
CONST DTP_BR_115200 = 9
; Errori in ricezione/trasmissione:
; successo
CONST ERR_RV_OK = 0
; timeout
CONST ERR_RV_TOUT = 1
; errore nel frame
CONST ERR_RV_FE = 2
; l'utente ha interrotto
CONST ERR_RV_ABORT = 3
; formato incorretto del frame
CONST ERR_RV_BAD_FRAME = 4
; checksum errato
CONST ERR_RV_BAD_CRC = 5
; errore di sequenziazione
CONST ERR_RV_BAD_SEQ = 6
; sorgente inattesa
CONST ERR_RV_BAD_SOURCE = 7
; parametri errati
CONST ERR_RV_BAD_PARAM = 8
; file esistente
CONST ERR_RV_EXIST = 9
; errore generico
CONST ERR_RV_GENERIC = 10
; Costanti per la creazione del file (in ricezione/trasmissione)
CONST DTP_CREATE_APPEND = 3
CONST DTP_CREATE_RENAME = 2
CONST DTP_CREATE_NEW = 1
CONST DTP_CREATE_ALWAYS = 0
; Parametri di configurazione
; ---------------------------
; Porta seriale
COMPORT = DTP_COM1
; Baud rate
COMSPEED = DTP_BR_38400
; Terminatore
POSTFIX = CHR(13)
; Ritardo interlinea
PACE = 0.02
; Intervallo di polling
POLLINTERVAL = 1
; Timeout (in millisecondi) per la risposta del terminale
TIMEOUT = 1000
; Nome del file (completo di percorso) sul terminale
FILENAME = "C:\\DATI.TXT"
; Nome del file temporaneo, sul quale ricevere i dati
TEMPFILE = "C:\\DTPS.TMP"
; Rimuove il file al termine della trasmissione
KILLFILE = 0
; Indica se si deve forzare l'uscita sul DTPS al termine della trasmissione
QUITAFTERRX = 1
; ---------------------------
; Apre la porta seriale
CS = DTPOpenClient(COMPORT, COMSPEED)
IF EQ(CS, 0)
!ifndef SERVICE
CONSOLELN "Impossibile aprire la porta " COMPORT "."
!endif
ABORT 2
FI
; Imposta il timeout per la verifica presenza
DTPSetFailTimeout(CS, TIMEOUT)
P = STRRSTR(FILENAME, "\\")
IF NEQ(P, 0)
PATH = LEFT(FILENAME, DEC(P))
IF AND(EQ(STRLEN(PATH), 2), STREQ(RIGHT(PATH, 1), ":"))
PATH = PATH "\\"
FI
NAME = RESTFROM(FILENAME, INC(P))
ELSE
PATH = ""
NAME = FILENAME
FI
WHILE 1
; Attende l'intervallo di poll
SLEEP(POLLINTERVAL)
; Se non è un servizio e l'utente ha premuto ESC, esce
!ifndef SERVICE
IF KBDHIT()
IF EQ(GETCH(), 27)
BREAK
FI
FI
!endif
; Verifica la presenza del terminale
RESULT = DTPPing(CS)
IF EQ(RESULT, 0)
; Verifica se esiste il file da scaricare
IF ISNOTEMPTY(PATH)
RESULT = DTPChDir(CS, PATH)
FI
RESULT = DTPSetAttrib(CS, NAME, 0, 0xFFFF, 0xFFFF)
IF NEQ(RESULT, 0)
CONTINUE
FI
; Rimuove il file temporaneo
FREMOVE(TEMPFILE)
; Riceve il file dal terminale
RESULT = DTPFileRx(CS, FILENAME, TEMPFILE, DTP_CREATE_ALWAYS)
!ifndef SERVICE
SWITCH RESULT
ON ERR_RV_OK
msg = ""
ON ERR_RV_TOUT
msg = "Timeout nella ricezione"
ON ERR_RV_FE
msg = "Errore nel frame"
ON ERR_RV_ABORT
msg = "L'utente ha interrotto"
ON ERR_RV_BAD_FRAME
msg = "Formato incorretto del frame"
ON ERR_RV_BAD_CRC
msg = "Checksum errato"
ON ERR_RV_BAD_SEQ
msg = "Errore di sequenziazione"
ON ERR_RV_BAD_SOURCE
msg = "Sorgente inattesa"
ON ERR_RV_BAD_PARAM
msg = "Parametri errati"
ON ERR_RV_EXIST
msg = "File esistente"
ON ERR_RV_GENERIC
msg = "Errore generico"
OFF
IF NEQ(RESULT, 0)
CONSOLELN "Errore: " msg
FI
!endif
IF EQ(RESULT, 0)
IF KILLFILE
DTPDelete(CS, FILENAME, DTP_DELETE_ALL)
FI
IF QUITAFTERRX
DTPExit(CS)
FI
EMULATEKBD(TEMPFILE)
FI
FI
LOOP
; Chiude la porta
RESULT = DTPCloseClient(CS)
ABORT 0
FUNCTION EMULATEKBD(tempfile)
h = FOPEN(tempfile, 1)
IF EQ(h, -1)
RETURN
FI
WHILE NOT(FEOF(h))
l = FREADLN(h)
; Se si vuole selezionare una particolare finestra, si può utilizzare
; un'espressione simile alla seguente:
; W32SETFOCUS(W32FINDWINDOW("*ULTRAEDIT-32*"))
W32SENDKEYS(KTrans(l) _POSTFIX)
SLEEP(_PACE)
LOOP
; Variante con salvataggio/ripristino finestra corrente e selezione blocco notes
; ; Preleva la finestra corrente
; hOld = W32GETFOCUS()
;
; ; Cerca il blocco notes
; hNew = W32FINDWINDOW("*Blocco note*")
; IF EQ(hNew, 0)
; ; Non trovato - lo lancia
; W32SHELL("NOTEPAD.EXE")
; ; Attende un secondo che si renda disponibile
; SLEEP(1)
; ; Cerca la sua finestra nuovamente
; hNew = W32FINDWINDOW("*Blocco note*")
; FI
; ; Se trovato, seleziona la sua finestra ed invia i dati
; IF NEQ(hNew, 0)
; W32SETFOCUS(hNew)
; WHILE NOT(FEOF(h))
; l = FREADLN(h)
; W32SENDKEYS(KTrans(l) _POSTFIX)
; SLEEP(_PACE)
; LOOP
; ELSE
; ; Impossibile aprire il blocco notes - dati persi!
; FI
; W32SETFOCUS(hOld)
FCLOSE(h)
RETURN
FUNCTION KTrans(s)
l = STRLEN(s)
r = ""
FOR x = 1 TO l
c = SUBSTR(s, x, 1)
; Mappatura dei caratteri speciali: caratteri che non si trovano
; sulla tastiera potrebbero richiedere l'introduzione della sequenza
; con ALT + numero
SWITCH c STREQ
ON "~"
r = r "{ALT DOWN}{NUMPAD1}{NUMPAD2}{NUMPAD6}{ALT UP}"
ON "{"
r = r "{ALT DOWN}{NUMPAD1}{NUMPAD2}{NUMPAD3}{ALT UP}"
ON "}"
r = r "{ALT DOWN}{NUMPAD1}{NUMPAD2}{NUMPAD5}{ALT UP}"
ON "+", "^", "%", "(", ")", "[", "]"
r = r "{" c "}"
OTHER
r = r c
OFF
NEXT
RETURN r