Conversione del gestionale ipot da Visual
Basic a C++
Luca Vezzaro
Dipartimento di Matematica Pura ed Applicata
Università degli studi di Padova
7 Aprile 2007
Sommario
L'utilizzo di strumenti e linguaggi di programmazione proprietari e non portabili
è molto diuso nel settore produttivo odierno. La ragione è che la specicità di
questi strumenti aiuta ad accelerare i tempi di sviluppo a breve termine, a costo
della portabilità e di una diminuzione della manutenibiltà a medio e a lungo
termine dei prodotti.
In questo trattato verrà esposta l'esperienza che ha portato alla realizzazione
di ipot OS5, conversione del gestionale ipot OS4 dal linguaggio Visual Basic
al linguaggio C++ con l'obiettivo di realizzarne una versione portabile, con un
occhio di riguardo anche per la manutenibilità e l'estensibilità.
Il linguaggio in cui è scritto l'applicativo originale non è stata l'unica barriera al raggiungimento della portabilità, anzi, come verrà descritto in seguito,
l'ostacolo più grande è stato posto dalle periferiche di scambio dati dedicate.
Ringraziamenti
In primo luogo si desiderano ringraziare gli amici Alessio Miozzi (hilkin@gmail.
com)
e Matteo Settenvini ([email protected]) per consigli sulla forma e
leggibilità del presente documento. Matteo ha inoltre fornito utili suggerimenti
sull'utilizzo di GTKmm.
Utile è stato anche il contributo di Tim Roberts ([email protected]) per le
preziose informazioni sul funzionamento dello standard USB e per direzioni sul
corretto utilizzo di libusb anche se, purtroppo, le nozioni che ha trasmesso non
sono mai state utilizzate durante lo sviluppo vero e proprio del progetto, ma
solo nella fase di prototipazione.
Dopodichè vorrei ringraziare gli sviluppatori di Lyx, per aver fatto sì che il
presente documento sia presentato in modo elegante e professionale senza che
AT X direttamente.
l'autore sia mai stato costretto ad utilizzare L
E
Inne non trascurabile è stato il contributo di Wikipedia per l'approfondimento di alcune nozioni tecniche (e non) su USB, ODBC e sulle metodologie
Agile.
1
Indice
1 Introduzione
4
1.1
Motivazione . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4
1.2
L'applicazione in Visual Basic
. . . . . . . . . . . . . . . . . . .
4
1.2.1
Interfaccia . . . . . . . . . . . . . . . . . . . . . . . . . . .
7
1.2.2
Architettura
1.3
. . . . . . . . . . . . . . . . . . . . . . . . .
9
Le periferiche . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
9
1.3.1
helper21 . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.3.2
ikey e reader
1.3.3
. . . . . . . . . . . . . . . . . . . . . . . . .
1.3.2.1
Installazione
. . . . . . . . . . . . . . . . . . . .
1.3.2.2
Comunicazione . . . . . . . . . . . . . . . . . . .
11
13
14
14
Radiofrequenza, GSM
. . . . . . . . . . . . . . . . . . . .
15
1.3.3.1
Installazione
. . . . . . . . . . . . . . . . . . . .
16
1.3.3.2
Comunicazione . . . . . . . . . . . . . . . . . . .
16
1.4
Il processo di conversione
. . . . . . . . . . . . . . . . . . . . . .
16
1.5
Panoramica Dei Contenuti . . . . . . . . . . . . . . . . . . . . . .
20
2 Concetti di base
2.1
21
USB . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
21
2.1.1
Endpoint e Pipe
. . . . . . . . . . . . . . . . . . . . . . .
21
2.1.2
Modalità di Trasferimento . . . . . . . . . . . . . . . . . .
22
2.1.3
Descrittori . . . . . . . . . . . . . . . . . . . . . . . . . . .
23
2.1.4
Enumerazione
23
2.1.5
Ri-enumerazione
. . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . .
24
2.2
ODBC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
24
2.3
Metodologie Agile
24
. . . . . . . . . . . . . . . . . . . . . . . . .
3 Studio di fattibilità e prototipazione
3.1
3.2
3.3
3.4
Comunicazione con la periferica ikey reader attraverso libusb
26
.
26
3.1.1
Obiettivi
. . . . . . . . . . . . . . . . . . . . . . . . . . .
26
3.1.2
Risultati . . . . . . . . . . . . . . . . . . . . . . . . . . . .
27
Comunicazione con la periferica ikey reader su Windows . . . .
28
3.2.1
Obiettivi
29
3.2.2
. . . . . . . . . . . . . . . . . . . . . . . . . . .
Risultati . . . . . . . . . . . . . . . . . . . . . . . . . . . .
29
Scrittura degli Archivi su database . . . . . . . . . . . . . . . . .
30
3.3.1
Obiettivi
. . . . . . . . . . . . . . . . . . . . . . . . . . .
31
3.3.2
Risultati . . . . . . . . . . . . . . . . . . . . . . . . . . . .
31
Interfaccia graca . . . . . . . . . . . . . . . . . . . . . . . . . . .
31
3.4.1
32
Obiettivi
. . . . . . . . . . . . . . . . . . . . . . . . . . .
2
3
INDICE
3.4.2
Risultati . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4 Analisi dei requisiti e dell'architettura
32
35
4.1
Requisiti funzionali . . . . . . . . . . . . . . . . . . . . . . . . . .
4.2
Requisiti non funzionali
. . . . . . . . . . . . . . . . . . . . . . .
35
36
4.3
Specica dell'interfaccia
. . . . . . . . . . . . . . . . . . . . . . .
36
4.3.1
Il frame principale
. . . . . . . . . . . . . . . . . . . . . .
36
4.3.2
Organizzazione delle sezioni . . . . . . . . . . . . . . . . .
38
4.4
Analisi architetturale . . . . . . . . . . . . . . . . . . . . . . . . .
39
4.5
Pianicazione . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
39
4.5.1
Incremento n. 1
. . . . . . . . . . . . . . . . . . . . . . .
40
4.5.2
Incremento n.2
. . . . . . . . . . . . . . . . . . . . . . . .
41
4.5.3
Incremento n.3
. . . . . . . . . . . . . . . . . . . . . . . .
41
4.5.4
Incremento n.4
. . . . . . . . . . . . . . . . . . . . . . . .
42
5 Sviluppo incrementale
5.1
5.2
5.3
5.4
43
Incremento n. 1 . . . . . . . . . . . . . . . . . . . . . . . . . . . .
43
5.1.1
Progettazione . . . . . . . . . . . . . . . . . . . . . . . . .
43
5.1.2
Sviluppo . . . . . . . . . . . . . . . . . . . . . . . . . . . .
46
5.1.3
Verica
48
5.1.4
Conclusioni . . . . . . . . . . . . . . . . . . . . . . . . . .
Incremento n.2
. . . . . . . . . . . . . . . . . . . . . . . . . . . .
49
. . . . . . . . . . . . . . . . . . . . . . . . . . . .
49
5.2.1
Progettazione . . . . . . . . . . . . . . . . . . . . . . . . .
49
5.2.2
Sviluppo . . . . . . . . . . . . . . . . . . . . . . . . . . . .
51
5.2.3
Verica
52
5.2.4
Conclusioni . . . . . . . . . . . . . . . . . . . . . . . . . .
Incremento n.3
. . . . . . . . . . . . . . . . . . . . . . . . . . . .
52
. . . . . . . . . . . . . . . . . . . . . . . . . . . .
52
5.3.1
Progettazione . . . . . . . . . . . . . . . . . . . . . . . . .
52
5.3.2
Sviluppo . . . . . . . . . . . . . . . . . . . . . . . . . . . .
53
5.3.3
Verica
54
5.3.4
Conclusioni . . . . . . . . . . . . . . . . . . . . . . . . . .
55
Deployment e Validazione . . . . . . . . . . . . . . . . . . . . . .
55
6 Conclusione
. . . . . . . . . . . . . . . . . . . . . . . . . . . .
57
Capitolo 1
Introduzione
1.1
Motivazione
E' dicile che un'applicazione non portabile scritta in un linguaggio proprietario
come l'Originale possa essere trasportata automaticamente nel linguaggio C++
e, anche se ciò fosse possibile, il tempo necessario potrebbe essere superiore a
quello richiesto da una conversione manuale. In ogni caso il prodotto risultante
sarebbe decisamente dicile, se non impossibile, da manutenere.
Oltretutto, la presenza di periferiche ad-hoc, e l'iniziale assenza di un driver
di sistema per piattaforme diverse da Windows, rende il raggiungimento della
portabilità totale potenzialmente impossibile.
1.2
L'applicazione in Visual Basic
L'applicativo ipot OS4 è un gestionale destinato alle realtà in cui è necessario monitorare, immagazzinare e organizzare dati di peso raccolti attraverso
macchinari di carico-scarico (ad es. scavatori).
Si avvale di un sosticato sistema di pesatura sviluppato da
VEI Group
(http://www.veigroup.com), basato su un apparecchio stand-alone denominato helper21 che immagazzina le
Movimentazioni e le associazioni tra esse ed
Archivi.
entità presenti nel database denominato
4
CAPITOLO 1.
INTRODUZIONE
5
Figura 1.1: Rappresentazione concettuale delle Movimentazioni (il susso _M
su Ricetta serve per indicare che si tratta di un'entità distinta dall'omonima
entità appartenente agli Archivi)
In breve, un Carico è una movimentazione costituita da un solo prodotto,
mentre una Ricetta_M è una movimentazione con al più 10 prodotti, ognuno
con un proprio limite di peso denito nella Ricetta_A associata al momento
della pesatura (come illustrato in gura 1.11).
Figura 1.2: Rappresentazione concettuale degli Archivi (il susso _A su Ricetta serve per indicare che si tratta di un'entità distinta dall'omonima entità
appartenente alle Movimentazioni)
CAPITOLO 1.
6
INTRODUZIONE
L'apparecchio helper21 è anche dotato di una
Congurazione interna che
è parzialmente modicabile attraverso l'applicazione.
Figura 1.3: Rappresentazione concettuale della Congurazione
Nella Congurazione, i Dati Impianto comprendono le impostazioni relative
al software di misurazione del peso, alle unità di misura e alla modalità di trasferimento utilizzata da helper21. I Dati di Sistema comprendono le password
per la limitazione dell'accesso a helper21 e le impostazioni per la stampante dedicata il cui supporto nell'Originale era ancora in fase embrionale. Caricato Da
identica il mezzo su cui helper21 è installato e/o il conducente dello stesso. Gli
Attrezzi conservano le impostazioni di al più 4 dispositivi meccanici responsabili
dell'eettiva misurazione del peso.
La comunicazione tra helper21 e l'applicazione può poi avvenire attraverso
il dispositivo di memorizzazione ikey (che viene letto/scritto dal relativo ikey
reader), radiofrequenza o GSM.
CAPITOLO 1.
INTRODUZIONE
7
1.2.1 Interfaccia
Figura 1.4: Come si presenta l'applicazione appena avviata
Come si può vedere in gura 1.4, l'applicazione non ha un aspetto tradizionale,
l'interfaccia graca infatti ha uno stile fortemente personalizzato, personalizzazione che non avviene lavorando a livello del toolkit graco, ma attraverso
posizionamenti assoluti e sovrapposizione di oggetti graci.
Per far sì poi che l'aspetto dell'applicazione mantenga una certa proporzionalità, ad ogni risoluzione utilizzata corrisponde un riposizionamento assoluto
di tutti gli oggetti dell'interfaccia, utilizzando costanti hard-coded nel codice.
CAPITOLO 1.
INTRODUZIONE
8
Figura 1.5: Una tipica sotto-sezione: gestione Archivi
I menu per la scelta delle operazioni, come si può vedere in gura 1.5, sono costituiti da liste di icone, una scelta non rara tra le applicazioni moderne,
così come per i form di ricerca e inserimento dati e per le tabelle di visualizzazione dati, anche se non mancano peculiarità che rendono anche questa parte
dell'interfaccia poco convenzionale.
Figura 1.6: Esempio di form di inserimento: Automezzi
CAPITOLO 1.
9
INTRODUZIONE
1.2.2 Architettura
Una sostanziale porzione della parte logica dell'applicazione è costituita da due
le organizzati in procedure, uno dei quali risultato di una quasi totale trasposizione del codice in Turbo Pascal di un programma d'esempio fornito dal
produttore delle periferiche dedicate.
Aspetti come la gestione dei dati nel database attraverso l'interfaccia graca
non fanno uso di codice aggiuntivo, come è abitudine fare in C++ o in Java,
dato che Visual Basic permette di implementare gran parte di questo aspetto
di un'applicazione attraverso il suo editor graco interattivo.
1.3
Le periferiche
Parte integrante del sistema gestionale
ipot sono le periferiche di misurazione
e scambio dati sviluppate da VEI Group.
Figura 1.7: Tutti i possibili percorsi dei dati.
In gura 1.7 sono visibili tutti i dispositivi di scambio dati e
helper21, che
è già stato menzionato in precedenza, e verrà discusso nella prossima sezione (
a pagina 11). Nella stessa gura è poi possibile osservare la direzione in cui le
entità possono essere trasferite per ogni periferica di scambio:
ikey (sezione 1.3.2
21RFlink e
a pagina 13) supporta il trasferimento di tutte le entità, mentre
21GSMlink (sezione 1.3.3 a pagina 15) sono, rispettivamente, le periferiche per
la comunicazione in radiofrequenza e GSM e supportano solo le Movimentazioni.
CAPITOLO 1.
INTRODUZIONE
10
Figura 1.8: Le varie modalità in cui è possibile ottenere dati da helper21
Figura 1.9: L'unica modalità in cui è possibile trasferire dati verso helper21:
tramite ikey
CAPITOLO 1.
11
INTRODUZIONE
1.3.1 helper21
Figura 1.10: L'apparecchio helper21 accesso
helper21
è un apparecchio posizionato sui mezzi che eettuano le operazioni
di carico (ossia le Movimentazioni).
Si occupa di gestire i dati di peso e di
associarli alle entità coinvolte nell'operazione.
CAPITOLO 1.
INTRODUZIONE
Figura 1.11: Operazioni coinvolte nella creazione di una movimentazione.
12
CAPITOLO 1.
13
INTRODUZIONE
E' possibile eettuare più pesate per uno stesso prodotto, da qui il nome
dell'azione Pesate. I valori di peso vengono però tutti sommati in modo da
creare un unico valore di peso (il numero di pesate eettuato viene comunque
salvato nel caso fosse necessario conoscerlo).
helper21 memorizza tutte le movimentazioni valide (e quelle non inviate
correttamente tramite radiofrequenza o GSM), ed è poi possibile trasferire manualmente queste in qualsiasi momento.
Una volta che una movimentazione è stata trasferita correttamente viene
cancellata dalla memoria di helper21.
1.3.2 ikey e reader
Figura 1.12: ikey
Il funzionamento di
ikey è assimilabile a quello di una comune chiavetta USB,
anche se la sua particolare conformazione sica (e probabilmente anche la sua
implementazione elettronica) fa in modo che sia dicile se non possibile utilizzarla con dispositivi diversi dall'apposito
reader
e da
helper21.
Quando
utilizzata con questi ultimi, comunque, si comporta semplicemente da dispositivo di memorizzazione dati, e funge da
l'applicazione e helper21.
vettore di comunicazione
dati tra
CAPITOLO 1.
14
INTRODUZIONE
Figura 1.13: ikey reader
Ciò che è importato eettivamente allo scopo di realizzare la conversione
è stata la comprensione del meccanismo di comunicazione tra codice C++ e
reader. In seguito verrà riassunto in breve come questo procedimento avviene,
si faccia riferimento alla documentazione fornita dal produttore per maggiori
dettagli [VEI-FW].
1.3.2.1 Installazione
La periferica è connessa al PC tramite USB, ma essa non viene riconosciuta
come una periferica particolare dal sistema operativo nchè non viene installato
il driver, che è disponibile solo per Windows.
Il driver non è indispensabile per la comunicazione attraverso il bus USB,
dato che si tratta di un protocollo standard. L'eettiva necessità di un driver è
originata dal fatto che il chip utilizzato da ikey reader
non è dotato di memo-
ria non-volatile (es. EPROM o FLASH), perciò deve esserci una componente
responsabile del
download
del rmware all'interno del dispositivo.
della periferica, appunto, installa un
servizio
Il driver
responsabile di eettuare il do-
wnload ogni qualvolta la periferica viene connessa al bus USB. Per semplicare
la programmazione viene successivamente installato un driver generico fornito
dal produttore del chip, che permette l'utilizzo della periferica attraverso delle
API semplicate [CY4604].
Questa seconda installazione è possibile grazie al
processo di ri-enumerazione (sezione 2.1.5 a pagina 24).
1.3.2.2 Comunicazione
La comunicazione con il rmware della periferica avviene in pacchetti di 64
byte, che non hanno particolare signicato singolarmente, a parte il primo che
contiene informazioni sulla dimensione dei dati che si è in procinto di comunicare
o su errori di lettura. Una volta raccolti tutti i dati e concatenati in un unico
buer, essi vanno interpretati come un array
non omogeneo di strutture C,
contigue nel buer.
anche se le aree contenenti oggetti di uno stesso tipo sono
CAPITOLO 1.
INTRODUZIONE
15
Figura 1.14: Esempio di Archivi con 3 oggetti per tipo
Alcune tipologie di oggetti sono anche ordinate sulla base del valore di
una stringa (che solitamente è il nome), e contengono un campo denominato
puntatore che identica univocamente gli oggetti.
La ne di un blocco contenente strutture contigue è solitamente denita dal
valore del campo puntatore, oppure è ssata a priori per blocchi di dimensione
ssa.
La ricostruzione dei valori avviene applicando le seguenti convenzioni:
•
I valori
interi sono senza segno e possono essere lunghi da 1 a 4 byte, e
ordinati in modo big-endian.
•
I valori
reali
sono di 4 byte, ordinati in modo big-endian, e codicati
secondo lo standard IEEE 754.
•
Le
stringhe sono di lunghezza ssa e non sono null-terminated, ma nel ca-
so in cui il testo sia più corto della stringa, è presente un padding composto
da caratteri spazio: ' '.
1.3.3 Radiofrequenza, GSM
Figura 1.15: Il dispositivo 21GSMlink
CAPITOLO 1.
16
INTRODUZIONE
Figura 1.16: Il dispositivo 21RFlink
La comunicazione RF (radiofrequenza) o GSM avviene attraverso una coppia di
dispositivi, rispettivamente di tipo 21RFlink o 21GSMlink.
1.3.3.1 Installazione
L'installazione è semplicissima, basta connettere uno dei dispositivi a helper21,
e l'altro a una porta seriale del PC. I dispositivi sono diversi in quanto helper21
non dispone di porta seriale. Non è poi necessario installare driver o altro per
utilizzare i dispositivi, con grande benecio per la portabilità.
1.3.3.2 Comunicazione
Per la comunicazione RF, è helper21 che invia i dati, quindi l'applicazione deve
in qualche modo essere avvisata quando dei dati sono in arrivo. In Visual Basic
ciò viene fatto tramite eventi.
Per la comunicazione GSM è inoltre possibile
chiamare helper21 e richiedere
l'invio dei dati.
A prescindere dal metodo, il formato dei dati ricevuti è lo stesso, e consiste di
una stringa di campi di lunghezza ssa separati dal carattere '@', eventualmente
seguito dal carattere '{' nel caso in cui i dati consistano di un gruppo di Movimentazioni (ricevute utilizzando l'invio manuale di helper21 o come riposta
di una chiamata GSM da parte dell'applicazione).
In ogni caso, una Movi-
mentazione consiste sempre di un numero sso di campi, quindi l'invio di una
Movimentazione singola viene gestita allo stesso modo dell'invio di un gruppo
di Movimentazioni contenenti una sola entità.
I valori
interi
sono codicati in esadecimale, mentre le
stringhe
sono co-
dicate nello stesso modo in cui le codica l'ikey reader (sezione 1.3.2.2 a
pagina 14).
1.4
Il processo di conversione
Idealmente, sarebbe stato possibile eettuare la conversione senza mai lanciare
l'Originale, basandosi solo sul codice sorgente della stessa. Ma considerando la
CAPITOLO 1.
17
INTRODUZIONE
dimensione della base di codice e il ridotto livello di suddivisione logica dello
stesso, alla ne ci si è basati principalmente sul comportamento a run-time
dell'Originale.
Naturalmente, per comprendere la logica di funzionamento di
operazioni complesse come quelle di trasferimento con le periferiche dedicate è
stato necessario leggere e comprendere alcune porzioni di codice.
Prima di procedere allo sviluppo vero e proprio, c'è stata una fase di studio
del dominio e di valutazione della fattibilità eettiva del progetto in cui sono
stati sviluppati diversi piccoli prototipi indirizzati all'esplorazione di speciche
problematiche.
Il responso di questa fase è stato solo parzialmente positivo,
infatti il raggiungimento della portabilità totale del Risultante si è dimostrato un
traguardo dicilmente raggiungibile nel tempo a disposizione date le dicoltà
incontrate nei tentativi di far funzionare la periferica ikey reader su Linux.
E' stato scelto il modello di sviluppo
incrementale,
in quanto i requisiti
erano tutti denibili all'inizio e perchè suddividendo lo sviluppo in incrementi è
più semplice monitorare i progressi eettuati (e quindi rispettare la pianicazione) e correggere gli errori identicati durante il processo di verica. Trattandosi
di un progetto individuale poi, è stato applicato un approccio Agile (sezione 2.3
a pagina 24) alla progettazione, quindi molti dei diagrammi UML che seguono
sono stati ottenuti tramite reverse-engineering del codice.
analisi dei requisiti è stata dedicata all'individuavincoli applicati ad essi da parte del
Una buona parte dell'
zione degli
attributi
delle entità e dei
database e dell'applicazione stessa, mentre i requisiti relativi a funzionalità dalla logica complessa sono stati deniti in modo vago così da non prolungare
troppo la fase di analisi nel tentativo di comprendere il codice relativo.
architettura di massima del sistema
Deniti i requisiti, è stata delineata l'
da realizzare, lasciando la denizione dei dettagli alla fase di progettazione di
ogni incremento, comunque ricordando che, data la scelta di utilizzare un approccio Agile alla progettazione, non sarebbe stato dedicato molto tempo alla
denizione a priori dei minimi dettagli di progettazione.
Figura 1.17: Architettura di massima
CAPITOLO 1.
18
INTRODUZIONE
Una volta ottenuta una suddivisione logica del sistema da sviluppare grazie
pianicazione della realizzazione su base incrementale, suddividendo le funzionalità nel
alla fase di Analisi Architetturale, è stato possibile procedere alla
modo seguente:
Incremento 1
Gestione Archivi, trasferimento tramite ikey su Windows
Incremento 2
Gestione Movimentazioni, gestione delle preferenze, trasferi-
mento tramite radiofrequenza e GSM
Incremento 3
Gestione Congurazione, gestione del Codice Autista, miglio-
ramenti alla GUI
Incremento 4 (Facoltativo)
Trasferimento tramite ikey su Linux, migliora-
menti all'usabilità, GUI potente come quella dell'Originale
L'attività di
progettazione
non ha comportato particolari dicoltà grazie
all'utilizzo di pattern aermati come Factory, Singleton e Observer.
Come già detto, il
codice è stato realizzato in C++ standard (precisamente,
IOS/IEC 14882, denito nel 1998), utilizzando poi librerie di terze parti per le
funzionalità non presenti nella libreria standard. Data la sostanziale dierenza
tra i linguaggi C++ e Visual Basic, la realizzazione di alcuni aspetti si è rivelata
complicata, mentre quella di altri è risultata semplicata.
Le complicazioni più importanti si sono vericate nella realizzazione della
GUI, infatti GTK, la libreria utilizzata, è basata su paradigmi diversi da quelli
di Visual Basic e le sue funzionalità avanzate sono poco documentate e, secondo
il parere dell'Autore, poco intuitive da utilizzare.
Quindi è stato necessario
giungere a compromessi per evitare di prolungare troppo i tempi di sviluppo.
CAPITOLO 1.
Figura
1.18:
19
INTRODUZIONE
Ecco
come
si
presenta
la
stessa
sezione
della
gura
1.5
della
gura
1.6
nell'applicazione in C++
Figura
1.19:
Ecco
come
si
presenta
lo
stesso
form
nell'applicazione in C++
Tra i vantaggi, la già citata portabilità, il supporto integrato alla localizzazione attraverso la combinazione
intltool/gettext, la maggiore compattezza e
leggibilità del codice di scambio dati con le periferiche dedicate, e la possibilità
di modicare e compilare il codice con strumenti liberamente disponibili, se non
CAPITOLO 1.
20
INTRODUZIONE
addirittura Open Source (una cosa impensabile per un'applicazione in Visual
Basic).
Inne un testing eettuato precocemente e continuamente ha assicurato la
prevenzione di bug o errori di progettazione gravi.
Purtroppo, per questioni di disponibilità temporali, il quarto incremento
(che comunque era facoltativo) non è mai stato realizzato.
1.5
Nel
Panoramica Dei Contenuti
Capitolo 2 vengono introdotti alcuni concetti necessari alla comprensione
dei capitoli seguenti, e può essere saltata o letta solo parzialmente da chi abbia
già familiarità con tali concetti.
Nel
Capitolo 3
viene esposto il lavoro svolto durante la fase di studio di
Capitolo 4 sono trattate l'analisi dei
Capitolo 5 illustra lo sviluppo vero e
fattibilità e prototipazione, mentre nel
requisiti e la pianicazione; inne il
proprio.
Nella
Conclusione vengono poi fatte alcune riessioni sui risultati ottenuti
e su ciò che non è stato possibile fare.
Capitolo 2
Concetti di base
In questo capitolo verrà fornita un'infarinatura di alcune nozioni necessarie alla
comprensione della restante parte del documento.
La prima sezione tratta dettagli tecnici sullo standard
USB
necessari per
comprendere le problematiche arontate nel primo prototipo (sezione 3.1 a pa-
Ri-enumerazione, la caratteristica
ikey reader su piattaforme sprovviste
gina 26), oltre che illustrare il concetto di
che complica ogni tentativo di utilizzare
di un driver specico.
La seconda e la terza sezione più che altro forniscono una panoramica su
ODBC e sulle metodologie Agile, rispettivamente. Nonostante sia presente un
Glossario a pagina 59, si è preferito mettere tali spiegazioni in questo capitolo
per mantenere il glossario breve e compatto.
2.1
L'
USB
Universal Serial Bus
(USB) è uno standard di comunicazione seriale che
consente di collegare diverse periferiche ad un computer.
La connessione di
molteplici dispositivi avviene attraverso la concatenazione di hub.
Esiste un
hub che è sempre presente, il cosiddetto root hub, esso è connesso direttamente
al controller USB.
La seguente descrizione illustra caratteristiche comuni alla versione 2.0 e
precedenti dello standard.
2.1.1 Endpoint e Pipe
I dispositivi e gli hub hanno associati dei pipe (canali logici), essi sono analoghi
alle pipeline nei sistemi Unix.
I pipe sono connessioni dal controller a una entità logica nel dispositivo
denominata endpoint.
Il termine è occasionalmente usato anche per riferirsi
all'intero pipe.
Questi endpoint (e i loro relativi pipe) sono numerati da 0 a 15 per ogni
direzione del usso di dati, così un dispositivo può avere no a 32 pipe attivi:
16 in ingresso all'host controller e 16 in uscita dal controller.
21
CAPITOLO 2.
CONCETTI DI BASE
22
Figura 2.1: Gli endpoint USB risiedono nel dispositivo connesso: i canali di
comunicazione con l'host sono deniti pipe
Ogni endpoint può trasferire dati in una sola direzione, in ingresso oppure
in uscita dal dispositivo, quindi ogni pipe è unidirezionale. L'endpoint 0 è però
riservato per la gestione del bus in entrambe le direzioni, e quindi occupa due dei
32 endpoint. Tutti i dispositivi USB devono implementare l'endpoint 0, quindi
ci sono sempre un pipe in ingresso e uno in uscita numerati 0 per qualsiasi
dispositivo.
2.1.2 Modalità di Trasferimento
Nei pipe i dati sono trasferiti in pacchetti di diversa grandezza. Ogni pipe può
n
supportare una lunghezza massima di pacchetto, tipicamente si tratta di 2
byte, di conseguenza un pacchetto USB spesso contiene dati dell'ordine di 8, 16,
32, 64, 128, 256 no a 512 byte.
I pipe sono suddivisi in quattro dierenti categorie in base alle modalità di
trasferimento dati:
control transfer
tipicamente usati per brevi e semplici comandi al dispositivo;
esempio: codici di comando spediti attraverso il pipe 0
isochronous transfer
velocità di trasferimento garantita (spesso, ma non ne-
cessariamente, la più elevata possibile) anche se con possibile perdita di
dati; esempio: video o audio in tempo reale
interrupt transfer
per dispositivi che necessitano di risposte in tempo ridotto
(latenza garantita); ad esempio: dispositivi di puntamento e tastiere
bulk transfer
grandi trasferimenti sporadici che utilizzano tutta la banda ri-
manente disponibile (ma senza nessuna garanzia di velocità o latenza);
esempio: trasferimento di le
CAPITOLO 2.
CONCETTI DI BASE
23
L'host controller fa polling sul bus in attesa di traco, solitamente seguendo
una politica round-robin. Gli
interrupt transfer sui corrispettivi endpoint in
realtà non interrompono il traco sul bus: sono solo ordinati in modo da essere
processati più spesso.
2.1.3 Descrittori
Figura 2.2: Relazioni tra i vari descrittori
Per accedere ad un endpoint, è necessario ottenere una congurazione gerarchica. Il dispositivo connesso al bus ha un descrittore di dispositivo, che contiene
uno o più descrittori di congurazioni. Queste congurazioni spesso corrispondono a stati in cui si trova il dispositivo, ad esempio: attivo o basso consumo.
Ogni descrittore di congurazione ha sua volta uno o più descrittori di interfaccia, che descrivono alcuni aspetti del dispositivo, così che possa essere usato per
diverse nalità, ad esempio: una videocamera potrebbe avere sia un'interfaccia
audio che una video. Questi descrittori di interfaccia a loro volta hanno un set-
ting di default e possibilmente più setting alternativi che a loro volta hanno dei
descrittori di endpoint, come descritto precedentemente. Un endpoint potrebbe
comunque essere riutilizzato da diverse interfacce o interfacce alternative.
2.1.4 Enumerazione
Si parla di enumerazione quando il sistema operativo, all'atto dell'inserimento
di un dispositivo, ottiene la coppia VID/PID (Vendor ID/Product ID). Questa
coppia di valori numerici identica univocamente un dispositivo ed è ciò che permette al sistema operativo di determinare il driver più appropriato da utilizzare
per la periferica (a patto che sia necessario).
L'operazione può essere descritta dai seguenti passi:
1. Il sistema operativo invia una richiesta Get_Descriptor/Device all'endpoint zero (il dispositivo deve sempre rispondere sull'endpoint zero al
momento della connessione).
2. Il dispositivo risponde alla richiesta inviando i dati di identicazione.
3. Il sistema operativo invia una richiesta Set_Address che assegna un indirizzo univoco al dispositivo.
CAPITOLO 2.
24
CONCETTI DI BASE
4. Il sistema operativo invia altre richieste Get_Descriptor, per ottenere ulteriori informazioni. Da queste può capire quanti endpoint ha il dispositivo, i
suoi consumi energetici, le velocità di comunicazione supportate, la coppia
VID/PID e altro.
[EZ-REF, Sezione 1.9]
2.1.5 Ri-enumerazione
La ri-enumerazione è una tecnica usata specicamente da dispositivi USB il cui
rmware è salvato su memoria volatile (es. RAM).
Il dispositivo, anche se privo di rmware, fa in modo che si verichi una
prima enumerazione, così da permettere il
download del rmware.
Una volta che è stato eettuato il download del rmware, il chip all'interno
del dispositivo inizia l'esecuzione del codice di rmware. Una nuova enumerazione viene eettuata, e questa volta vengono esposti i descrittori del dispositivo
programmato. Per fare un esempio, il chip EZ-USB FX eettua questo processo simulando una disconnessione e riconnessione del dispositivo usando specici
segnali elettrici.
Una volta ri-enumerato, anche le richieste sull'endpoint 0 sono gestibili
totalmente, o in parte, dal codice del rmware.
[EZ-REF, Capitolo 5]
2.2
ODBC
Open Database Connectivity (ODBC) è una API standard per la connessione ai DBMS. Questa API è indipendente dai linguaggi di programmazione, dai
sistemi di database (DBMS) e dal sistema operativo. E' stata creata dall'SQL
Access Group e la sua prima release risale al Settembre 1992.
ODBC è un'interfaccia nativa alla quale si può accedere tramite linguaggi
che siano in grado di chiamare funzioni di librerie native. Nel caso di Microsoft
Windows, questa libreria è una DLL. La prima versione è stata sviluppata su
Windows; altre release sono state scritte per UNIX, OS/2 e Macintosh.
In aggiunta al software ODBC, è necessario un driver specico per poter
accedere ad ogni diverso tipo di DBMS. ODBC permette ai programmi che
lo utilizzano di inviare ai database stringhe SQL senza che ci sia bisogno di
conoscerne le API proprietarie. La connessione a una fonte dati ODBC avviene
attraverso un DSN (Database Source Name), una semplice stringa che associa
un driver a una fonte dati su un DBMS compatibile con lo stesso.
Grazie a ODBC, quindi, i programmi possono utilizzare qualsiasi DBMS per
cui sia disponibile un driver senza necessità di usare codice specico (a meno
che non si intenda utilizzare funzionalità esclusive di un certo DBMS).
2.3
Metodologie Agile
Le metodologie Agile sono nate per minimizzare il rischio di fallimento in progetti in cui la variabilità dei requisiti e l'incertezza del committente rispetto ad
essi sono i rischi principali.
CAPITOLO 2.
CONCETTI DI BASE
25
Nella maggior parte dei casi, queste metodologie prevedono lo sviluppo del
software in brevi iterazioni (lunghe in genere dalle 2 alle 8 settimane), eventualmente ristrette a nestre di tempo chiamate timebox (al termine delle quali
l'iterazione termina, a prescindere dal livello di completamento della stessa).
Ogni iterazione è un piccolo progetto a sè stante e deve contenere tutto
ciò che è necessario per rilasciare un piccolo incremento nelle funzionalità del
software: pianicazione (planning), analisi dei requisiti, analisi architetturale,
implementazione, test e documentazione. Alla ne di ogni iterazione, le priorità del progetto e la pianicazione sono rivalutate. La rapidità con cui viene
realizzato del software funzionante dà la possibilità al committente di fornire
feedback molto presto, minimizzando i rischi e i costi collegati a un eventuale
cambio dei requisiti.
Queste metodologie enfatizzando la comunicazione in tempo reale, meglio se
faccia a faccia rispetto a quella scritta, e il software sviluppato come principale
misura di progresso, anzichè la documentazione.
Una conseguenza di ciò è che gran parte dei diagrammi vengono realizzati in
modo collaborativo su grandi fogli di carta o lavagne, piuttosto che con strumenti
CASE (Agile modelling).
Questo non deve far pensare che in un progetto Agile la documentazione sia
assente, si cerca solo di ridurre al minimo la produzione di documenti che non
siano più di utilità dopo breve tempo, o che richiedano troppo lavoro per essere
aggiornati in seguito a un cambiamento dei requisiti.
[LAR05]
Capitolo 3
Studio di fattibilità e
prototipazione
Come è buona norma fare in ogni progetto non banale, anche nel nostro caso
è stato eettuato uno
studio di fattibilità,
attraverso la realizzazione di 4
prototipi indirizzati all'esplorazione di speciche aree del sistema da realizzare.
I prototipi sono descritti nell'ordine in cui sono stati sviluppati e sono:
1. Ricerca di una soluzione portabile per la comunicazione con
attraverso l'utilizzo di
2. Utilizzo di
libusb
ikey reader
ikey reader in modo non portabile su Windows utilizzando la
stessa API usata nell'Originale
3. Scrittura degli Archivi su
database e ricerca di un alternativa portabile
a quello dell'Originale in formato Microsoft Access
4. Realizzazione dell'
interfaccia graca in modo che sia il più simile pos-
sibile a quella dell'Originale
Al termine di questa fase è stato possibile vericare la fattibilità parziale del
progetto, dato il fallimento del primo prototipo.
La problematica al punto 1
è stata quindi portata in secondo piano per essere considerata come requisito
opzionale e non vincolante.
3.1
Comunicazione con la periferica ikey reader attraverso libusb
Un prerequisito essenziale per la completa conversione dell'Originale è la possibilità di utilizzare la periferica dedicata ikey reader su piattaforma nonMicrosoft, in quanto le API per la versione Windows [CY4604] sono disponibili
e sono le stesse usate dall'applicazione in Visual Basic.
3.1.1 Obiettivi
Vericare che sia possibile utilizzare tale periferica su Linux.
26
CAPITOLO 3.
STUDIO DI FATTIBILITÀ E PROTOTIPAZIONE
27
Per la periferica meno recente ikey reader OS3 , il driver è semplice, e quindi la realizzazione di un modulo di comunicazione in C++ standard dovrebbe
essere un'operazione assolutamente fattibile. Per prima cosa quindi si tenterà di
interfacciarsi a questa versione della periferica, per poi passare alla più recente.
3.1.2 Risultati
Il prototipo è stato sospeso perchè si stava rivelando troppo dispendioso in
termini di tempo, infatti l'attività di prototipazione si era ormai ridotta a un
tentativo di reverse-engineering del driver per Windows.
La prima problematica ad essere insorta è stata la dicoltà nell'interpretare
i messaggi di errore di
libusb, ad esempio gli errori causati dalla versione iniziale
del prototipo erano:
Windows:
Linux:
Memoria insuciente per eseguire l'operazione
error obtaining child information: Inappropriate ioctl for device
USB error: error submitting URB: No such le or directory
Anche una ricerca sul web non è stata utile per decifrare questi messaggi di
errore, e quindi si è deciso di inserire un post nel forum di
libusb-win32, che
non ha ricevuto risposte, esito che non è toccato al post inserito qualche giorno
dopo nella mailing list di
libusb [USBDEV-ML].
Le prime risposte ottenute in mailing list sottendevano la presenza di alcuni
errori dettati dall'inesperienza e dal fatto che il codice era basato su un articolo
[KR-HAR04] orientato a un dispositivo completamente diverso.
Ma anche in seguito all'applicazione dei consigli ricevuti le cose non sono
cambiate particolarmente, e gli errori si ripetevano alla stessa maniera.
I post successivi sono stati però più illuminanti, e hanno permesso l'individuazione del problema di base che ostacolava la comunicazione: il dispositivo in
nostro possesso era
programmabile
e necessitava quindi di un rmware, ma
non essendo dotato di memoria non-volatile (ad.es. EPROM o FLASH), doveva
esserci una componente responsabile del download del rmware all'interno del
dispositivo, operazione svolta dal driver della periferica sotto Windows.
L'obiettivo si è quindi spostato verso la ricerca di un metodo per l'estrazione
del rmware dalla periferica o dal driver per Windows.
Una volta ottenuto
il rmware, non dovrebbero esserci state ulteriori dicoltà, in quanto i kernel
recenti (versione 2.4.19 e superiori) supportano il caricamento del rmware per
i dispositivi EZ-USB [EZ-LINUX].
Non è stato possibile trovare soluzioni basate su strumenti di analisi del
traco USB che, essendo dei ltri per driver, sono inutilizzabili anchè una
periferica non dispone di un driver.
Infatti, il processo di installazione del dispositivo è eettuato in due fasi,
nella prima viene caricato il rmware, utilizzando comandi di basso livello che
non fanno utilizzo di alcun driver di periferica [EZ-REF], e nella seconda viene
installato un driver generico fornito dal produttore del chip interno al dispositivo
(http://www.cypress.com).
Dato che
Wine non poteva essere utile per applicazioni a così basso livello
Ndiswrapper, che emula il pro-
[Sto111406], le speranze sono state riposte su
cesso di installazione del driver per Windows della periferica, rendendo quindi
CAPITOLO 3.
STUDIO DI FATTIBILITÀ E PROTOTIPAZIONE
28
possibile in linea teorica l'individuazione del contenuto del pacchetto che invia
il rmware attraverso l'analisi dell'output di debug.
Ma prima che si potesse provare a percorrere questa strada, in mailinglist si è presentata una possibilità più allettante, ossia la possibilità di leggere
il rmware direttamente dal dispositivo (
Request 0xA0 [EZ-REF].
Con lo strumento di sviluppo Cypress
upload),
inviando il byte di Vendor
EZ-USB Control Panel per Win-
dows [EZ-DEVKIT], è stata questione di pochi click ottenere il rmware (apparentemente 8KB di dimensione). Il le contenente le informazioni copiate è
txt2hex forfxload, utilizzando la seguente
stato convertito nel formato Intel Hex attraverso l'utilizzo del tool
nito con EEP24C e passato come parametro a
riga di comando:
fxload -I ireaderv3.ihx
Invocazione che causa l'errore:
can't write 17 bytes external memory at 0x1b30
unable to download ireaderv3.ihx
Non conoscendo la tipologia esatta del chip, si è provato a usare il parametro
`-t fx2`:
fxload -t fx2 -I ireaderv3.ihx
La quale causa pure un errore:
can't write 17 bytes external memory at 0x10
unable to download ireaderv3.ihx
In entrambi i casi, la rimozione dal le di input dei byte in eccesso non ha
cambiato la situazione, il dispositivo non ha mai dato segni di eettuare la
ri-enumerazione (sezione 2.1.5 a pagina 24).
Per sicurezza, si è cercato di ripetere la procedura su Windows: per prima
cosa è stato rimosso il driver fornito dal produttore della periferica, e sostituito
con una versione modicata di quello generico solitamente installato in seguito
alla ri-enumerazione.
La modica apportata al driver è stata concentrata sul
le .inf (infomazioni di installazione del driver), e faceva in modo di disabilitare l'installazione e l'esecuzione di quella componente del driver che si occupa
dell'installazione del rmware.
Una volta installato il driver generico modicato, è stato eettuato il down-
EZ-USB Control
Panel [EZ-DEVKIT], scrittura il cui esito positivo è stato confermato da una
load (trasferimento dall'host verso il dispositivo) con il tool
lettura eettuata successivamente. Nonostante ciò, non si è stati in nessun modo
in grado di indurre il processo di ri-enumerazione.
3.2
Comunicazione con la periferica ikey reader su Windows
Era chiaro come fosse improbabile l'implementazione del supporto a ikey reader su Linux nel tempo assegnato, ma l'impossibilità di fornire tale supporto
CAPITOLO 3.
29
STUDIO DI FATTIBILITÀ E PROTOTIPAZIONE
su Windows sarebbe stata seriamente problematica per il proseguimento del
progetto.
Il supporto su Windows non era propriamente scontato, dato che l'API
della libreria originalmente chiamata Dll_From_VB.dll
1 era a basso livello, e
richiedeva una buona dimestichezza per essere utilizzata correttamente.
Notare che, essendo C++ il linguaggio in uso, sarebbe anche stato possibile
usare direttamente la libreria
CyAPI
[CY4604], ma ciò avrebbe richiesto un
ulteriore livello di conversione, che avrebbe portato solo ad un allungamento dei
tempi di sviluppo.
3.2.1 Obiettivi
•
Acquistare familiarità con la API fornita da Dll_From_VB.dll, che è a
basso livello: infatti essa lavora scambiando pacchetti di dati di al massimo
64 byte alla volta con la periferica USB.
•
Vericare che non ci siano ostacoli tecnologici all'utilizzo della suddetta
DLL.
3.2.2 Risultati
Si è riusciti subito a ottenere i puntatori alle funzioni nella DLL, ma alcune di
esse causavano un errore di run-time all'atto della chiamata, cosa imputabile al
fatto che la DLL era stata compilata senza usare le direttive di dllexport e senza
imporre il linking di tipo C sulle funzioni esportate.
Infatti, una volta ricompilata la DLL esportando le funzioni come è abitudine
fare nel mondo C/C++, le chiamate alle funzioni esportate venivano eettuate
correttamente.
Lo sviluppo del protipo è quindi proseguito, e la prima funzione ad essere stata implementata, sotto richiesta del Tutore, è stata quella dedicata alla
lettura della versione del rmware della periferica.
La seconda funzionalità ad essere stata sviluppata, più complessa, consisteva
nella lettura degli
Archivi
contenenti il database dei clienti, degli automezzi,
delle ricette, prodotti, etc. . .
Inne si è proceduti alla scrittura degli stessi Archivi sul dispositivo, dove
l'ostacolo più grande è stato il calcolo del checksum dei dati, infatti in lettura i
checksum erano stati ignorati. Fortunatamente, non è stato dicile comprendere il meccanismo di calcolo dal codice dell'Originale, anche grazie ai suggerimenti
del Tutore.
Per le zone di codice più a basso livello, la mancanza di type-safety del C++
è stata sfruttata abbondantemente per scrivere codice più compatto di quello in
Visual Basic. La dimensione del codice responsabile della lettura degli Archivi
(commenti e dichiarazioni di strutture di supporto escluse), è infatti passata
da circa 365 a 200 linee di codice, e nonostante il codice Visual Basic fosse
più robusto, non si ritiene la dierenza di dimensione sia giusticabile solo da
questo. Anche dal punto di vista della leggibilità è evidente un miglioramento.
Si compari (Visual Basic):
1 Una
libreria
intermedia
sviluppata
CyAPI.lib [CY4604], con Visual Basic
dall'Azienda
per
utilizzare
la
libreria
originaria,
CAPITOLO 3.
STUDIO DI FATTIBILITÀ E PROTOTIPAZIONE
30
' Salvo tutte le anagrafiche ricevute
ChkSumSysCalc = 0
Punt = 0
NrByteLetti = 0
ReDim Buffer_Anagrafica.RecordAnagrafica(0)
While Punt <> 65534
For Loop1 = 0 To LEN_RECORD_ANAGRAFICA - 1 'do begin
BufferAnagrafica.RecordAnagraficaSingBuf(Loop1) =
BufferApp(NrByteLetti + Loop1)
Next
BufferAnagrafica.RecordAnagraficaSing =
RicavaAnagrafica(BufferAnagrafica.RecordAnagraficaSingBuf)
NrByteLetti = NrByteLetti + LEN_RECORD_COMPL_ANAGRAFICA
Buffer_Anagrafica.RecordAnagrafica(
UBound(Buffer_Anagrafica.RecordAnagrafica)) =
BufferAnagrafica.RecordAnagraficaSing
VarWord = BufferAnagrafica.RecordAnagraficaSing.Puntatore
Punt = VarWord
ReDim Preserve Buffer_Anagrafica.RecordAnagrafica(
UBound(Buffer_Anagrafica.RecordAnagrafica) + 1)
Wend
con (C++):
std::vector<Anagrafica> anagrafe;
Buffer_Anagrafica* cur_ana = (Buffer_Anagrafica*)(data[0]);
do
{
// Il costruttore di Anagrafica si occupa solo di copiare
// i dati
anagrafe.push_back(Anagrafica(*cur_ana));
// sposta l'ID
anagrafe.back().Punt = Punt;
Punt = pack_lsb<2>(cur_ana->Punt);
// tra i record c'e' un separatore di 4 byte che va saltato
cur_ana = (Buffer_Anagrafica*)((unsigned char*)(cur_ana) +
sizeof(Buffer_Anagrafica) + 4);
}
while(Punt != 0xFFFE);
Questo prototipo ha dato i risultati sperati, e non dovrebbero esserci dicoltà
nell'implementazione del codice di scrittura e lettura per le altre entità gestite
dall'applicazione, dato che il meccanismo di base è lo stesso.
3.3
Scrittura degli Archivi su database
La strategia di deployment tipica dell'Originale prevedeva che fosse presente un
le di database in formato Microsoft Access (.mdb) in una sottocartella della
CAPITOLO 3.
STUDIO DI FATTIBILITÀ E PROTOTIPAZIONE
31
directory di installazione. Naturalmente, l'utilizzo di un le di database in quel
formato era un grosso ostacolo alla portabilità.
Oltretutto erano emerse altre possibilità per sopperire alla mancanza di un
driver su Linux per ikey reader, possibilità che sono state esplorate durante lo
sviluppo di questo stesso prototipo.
3.3.1 Obiettivi
•
Trovare un'alternativa semplice, portabile e leggera al database in formato
Access.
•
Utilizzare parte del codice del precedente prototipo per ricostruire e strutturare i dati prima di inserirli nel database, leggendoli da un dump binario
degli Archivi contenuti su ikey, in modo da assicurare la portabilità del
prototipo.
Provare a emulare il programma che produce il dump degli Archivi uti-
Wine,
lizzando
per vericare se questa è una strada percorribile per
soppiantare alla mancanza di un'interfaccia di programmazione per Linux.
•
Vericare se c'è una possibilità che il driver per Linux
cyport supporti il
chip contenuto nella periferica ikey reader OS4 [CY7C64713] (per ikey
reader OS3 non è stato possibile identicare il chip contenuto), in quanto
questo non è nella lista di quelli ucialmente supportati.
3.3.2 Risultati
Innanzitutto, la scelta del database è ricaduta su
SQLite,
e per assicurare
estensibilità si è deciso di aggiungere un ulteriore livello di astrazione attraverso
il driver ODBC di Christian Werner [Wer06].
ODBC scelta è
La libreria di programmazione
libodbc++ [FREEODBC], che presenta una API molto simile
a quella di JDBC.
Purtroppo
Wine
non implementava ancora l'API di Windows a un livello
sucientemente basso (ossia molto vicino all'hardware) per far funzionare l'applicazione che esegue il dump degli Archivi [Sto111406]. Fatto suggerito anche
dalla totale mancanza di un sistema per far funzionare i driver della periferica
nell'ambiente Wine [MOE06].
Per quanto riguarda
cyport, invece, non è stato possibile neppure compilar-
lo, fatto probabilmente imputabile all'obsolescenza del codice (l'ultima release
del pacchetto risale al 2003).
In conclusione, la parte relativa al database non ha creato sostanziali problemi, mentre si sono rivelati fallimentari gli ulteriori tentativi di far funzionare
la periferica ikey reader su Linux.
3.4
Interfaccia graca
L'interfaccia graca dell'Originale era piuttosto sosticata in quanto faceva ampio uso di oggetti graci personalizzati. Essendo poi realizzata con l'editor di
form di Visual Basic, non era portabile, quindi molto probabilmente andrà riscritta. Ma il requisito posto dall'Azienda di mantenere il più possibile intatto
l'aspetto dell'applicazione rendeva l'operazione tutt'altro che banale.
CAPITOLO 3.
STUDIO DI FATTIBILITÀ E PROTOTIPAZIONE
32
3.4.1 Obiettivi
Analizzare le possibilità di riutilizzo dell'interfaccia attuale e, se necessario,
scegliere la libreria graca più adatta allo scopo.
3.4.2 Risultati
Nessun toolkit portabile e liberamente disponibile che sia compatibile con le
esigenze di licensing dell'Azienda oriva un ambiente di sviluppo di interfacce
grache potente o, più correttamente, permissivo, come quello di Visual Basic.
In realtà la scelta non era poi così ampia, e i due candidati più validi si sono rivelati
wxWidgets e GTKmm , con la consapevolezza che, molto probabilmente,
per entrambe sarebbe stato necessario realizzare dei widget personalizzati per
ottenere l'aspetto desiderato. Date le precedenti esperienze di programmazione
dell'autore con GTKmm, esso è stato il toolkit preferenziale, wxWidgets sarebbe stato considerato solo se GTKmm si fosse dimostrato incapace di soddisfare
i nostri requisiti.
Dopo circa una giornata di lavoro, il massimo che si è riuscito a ottenere con
GTKmm è stata una nestra con lo sfondo richiesto, con all'interno un pulsante,
anch'esso con uno sfondo personalizzato, ma si sono incontrate dicoltà una
volta che si è cercato di cambiare lo sfondo del pulsante qualora venisse premuto,
così come faceva l'applicazione in Visual Basic.
Figura 3.1: Pulsante con sfondo
Come è facile notare, però, lo stile graco dell'Originale è simile a quello
utilizzato da Mac OS X, e una volta individuato un tema per GTK+ adatto
[GLOSSY], tutto si è semplicato, anche perchè buona parte del lavoro di design
dell'interfaccia può essere fatto con
Glade.
Oltretutto, essendo il tema basato
su immagini PNG, sembrava anche sucientemente personalizzabile.
CAPITOLO 3.
STUDIO DI FATTIBILITÀ E PROTOTIPAZIONE
33
Figura 3.2: Un esempio di Glossy P
Questa strategia ha indubbi vantaggi su quella utilizzata per lo sviluppo
dell'interfaccia in Visual Basic, primo fra tutti la manutenibilità e la possibilità
di gestire in modo quasi automatico la visualizzazione a diverse risoluzioni, a
dierenza del riposizionamento esplicito presente nel codice dell'Originale.
Una volta ottenuto un feedback positivo relativamente al look-and-feel dell'applicazione, il Tutore ha richiesto la realizzazione di alcuni form d'esempio
per l'inserimento e la ricerca di dati anagraci, la cui realizzazione non ha comportato particolari dicoltà. In questo frangente è stato utile usare delle convenzioni nell'organizzazione del le glade: le varie sezioni nella parte destra
dell'interfaccia sono state memorizzate all'interno di più nestre, visto che Glade non dà la possibilità di sovrapporre oggetti come in Visual Basic. E' stato
poi utilizzato il metodo
reparent_widget per visualizzare il contenuto di que-
ste nestre di supporto all'interno della sezione di destra.
reparent_widget
Prima di invocare
è però necessario liberare il contenitore di destinazione, e
in questo frangente è stato comodo usare come nome del primo antenato di una
sezione il nome della sezione stessa seguito da Parent. Con questo stratagemma, il cambio di sezione si è ridotto a poche righe di codice, a prescindere dal
numero di sezioni da gestire:
// Ottieni il widget corrispondente alla sezione di destra
Glib::ustring naturalize = _hpane->get_child2()->get_name();
// Ottieni il widget che originariamente era il padre di naturalize
Gtk::Container* natural_parent = NULL;
_glade->get_widget(naturalize + "Parent", natural_parent);
Glib::ustring to_open = <nome della sezione da aprire>;
// Sposta il widget nella sua posizione originaria nella gerarchia
CAPITOLO 3.
STUDIO DI FATTIBILITÀ E PROTOTIPAZIONE
34
if(to_open != naturalize)
_glade->reparent_widget(naturalize, *natural_parent);
// Installa il nuovo widget di sezione
_glade->reparent_widget(to_open, *_hpane);
Dopodichè, per ovviare alla mancanza di un supporto diretto all'utilizzo di dati
provenienti dal database come fonte per i controlli (ad.es. combo box ), è stata
utilizzata una convenzione nel nome dei controlli in modo da evitare la necessità
di creare delle query ad-hoc. Un esempio tipico è: Combo.DB/Customers/Name,
dove il presso Combo. è comodo perchè permette di utilizzare
get_widget_prex
per ottenere tutti i widget di un certo tipo, Customers è il nome della tabella
e Name il nome del campo usati come fonte per popolare la lista di scelte.
Figura 3.3: L'albero dei widget in
Glade
Capitolo 4
Analisi dei requisiti e
dell'architettura
L'analisi dei requisiti è partita dallo studio dei casi d'uso principali, che sono
poi stati suddivisi in casi d'uso più specici, per poterli descrivere nei dettagli.
I requisiti potevano essere elencati e descritti in profondità tutti dall'inizio, dati
gli obiettivi del progetto.
Visto il forte orientamento ai dati dell'applicazione, e ai numerosi vincoli da
rispettare anchè i dati fossero nel dominio dei valori accettati da helper21, la
prima parte dell'analisi dei requisiti è stata investita nella realizzazione di un da-
ta dictionary, ossia di una descrizione dei dati manipolati dall'applicazione, dei
vincoli che dovevano rispettare e delle loro relazioni con il database. Una volta
fatto questo, è stato possibile rendere molto compatti, leggibili e riutilizzabili
i casi d'uso, ad indicare come la parte logica dell'applicazione fosse veramente
ridotta.
Una porzione sostanziale dell'analisi dei requisiti è stata poi ricoperta dalla
specica dell'interfaccia graca, una descrizione compatta e organizzata dell'aspetto e del funzionamento della GUI.
In seguito è stato fatto uno studio dell'architettura di massima del sistema
da realizzare, suddividendolo in componenti.
Inne, con gli elementi ottenuti è stato possibile pianicare la fase di sviluppo
in modo che tutte le priorità e le dipendenze fossero prese in considerazione.
4.1
Requisiti funzionali
RF1:
il sistema
deve permettere di gestire le Movimentazioni
RF2:
il sistema
deve permettere di gestire gli Archivi
RF3:
il sistema
deve permettere di congurare helper21
RF4: deve essere possibile congurare vari aspetti del sistema
RF5:
il sistema
deve permettere lo scambio di dati con helper21
RF6: deve essere possibile salvare su ikey il codice autista, almeno su Windows
35
CAPITOLO 4.
4.2
ANALISI DEI REQUISITI E DELL'ARCHITETTURA
36
Requisiti non funzionali
RNF1:
l'interfaccia graca del sistema
deve
prevedere le stesse modalità
di
navigazione e operazione di ipot in modo che non sia necessario nessun
tipo di apprendimento per usare il sistema per chi già sa usare ipot
RNF2:
il sistema
deve poter funzionare su Linux, anche a costo di sacricare
RNF3
RNF3:
il sistema
dovrebbe
permettere lo scambio dei dati attraverso ikey
reader su Linux
RNF4:
il sistema
vorrebbe
migliorare ipot dal punto di vista dell'usabili-
tà prevedendo strumenti per aumentare l'ecienza degli utenti
4.3
Specica dell'interfaccia
Figura 4.1: Suddivisione logica della GUI
Come indicato in gura 4.1, è possibile suddividere l'interfaccia in 4 porzioni
che chiameremo frame.
Quando si farà
riferimento a un oggetto dell'interfaccia, si userà come pre-
sso il nome del frame in cui si trova, seguito da un punto, e successivamente
da un nome descrittivo dell'oggetto. Ad esempio U.Barra_di_navigazione o
D.Cestino.
4.3.1 Il frame principale
Ogni elemento nel frame principale è sempre visibile, a parte il pulsante D.Abilita
che è visibile solo se si sta utilizzando l'applicazione senza essersi autenticati e la
CAPITOLO 4.
ANALISI DEI REQUISITI E DELL'ARCHITETTURA
37
sezione (denizione di sezione nella pagina successiva) corrente richiede l'autenticazione per essere usata. Meritano particolare attenzione le seguenti porzioni
del frame:
1.
L'immagine U.VEI
Questa immagine è ssa, ha come tooltip la stringa
com
2.
http://www.veigroup.
e, se cliccato, apre il browser web predenito allo stesso indirizzo.
Il pulsante U.Nuovo
Questo pulsante è sensibile solo se si stanno modicando delle entità multiple. Se viene cliccato, viene salvato il record corrente (se è valido), e il
form viene azzerato per permettere l'inserimento di un nuovo record.
3.
Il pulsante U.Importa
Questo pulsante implementa un requisito non richiesto al nostro sistema.
4.
Il pulsante U.Esporta
Questo pulsante implementa un requisito non richiesto al nostro sistema.
5.
L'immagine U.ipot
Questa immagine è sempre visibile, e se cliccata termina le eventuali operazioni di modica in corso e lancia l'animazione di benvenuto. Inoltre,
nel caso di un trasferimento RF o GSM da helper21 verso l'applicazione,
questa icona viene sostiuita da un'animazione di notica.
Si trattano quindi di funzionalità puramente estetiche che non vengono
considerate prioritarie da questa analisi.
6.
U.Barra_di_navigazione
Questa porzione dell'interfaccia visualizza il nome della sezione corrente
con a anco un'icona che rappresenta la sezione stessa.
7.
Il pulsante U.Indietro
Questo pulsante permette di selezionare il record precedente per permetterne la modica. E' sensibile solo se si stanno modicando entità multiple
e, naturalmente, se non si è già sul primo record.
8.
Il pulsante U.Avanti
Questo pulsante permette di selezionare il record successivo, similmente a
come avviene per U.Indietro.
9.
Il pulsante U.Esci
Chiude l'applicazione.
10.
Il frame L
Il frame L, è costituito da una colonna di icone, e viene utilizzato per
eettuare la scelta delle sezioni del primo livello, che vengono attivate
selezionando la relativa icona.
11.
Il frame R
In questo frame viene visualizzata la sezione corrente, che può ad esempio
essere una sezione di scelta, organizzata a icone alla stessa maniera del
frame L, o una sezione organizzata in schede che permette di modicare,
cercare o visualizzazione i record.
CAPITOLO 4.
12.
ANALISI DEI REQUISITI E DELL'ARCHITETTURA
38
Il pulsante D.Abilita
Se cliccato, causa la richiesta della password all'utente per poter utilizzare
le funzionalità che richiedono autenticazione.
13.
Il pulsante D.Cestino
Questo pulsante è sensibile solo se si stanno modicando o visualizzando
entità multiple. Se viene cliccato, vegono eliminati i record selezionati.
4.3.2 Organizzazione delle sezioni
Con
sezione si vuole intendere una porzione di interfaccia che viene visualizzata
sul frame R. Una sezione può essere costituita da una lista di icone, da una
visualizzazione a schede, o altro ancora. . .
La seguente gerarchia dovrebbe spiegarsi da sola, le sezioni principali sono
quelle al primo livello, e sono attivabili attraverso il frame L. Se una sezione
ha dei gli in questa gerarchia, signica che essa visualizza sul frame R delle
icone attraverso cui accedere ad ulteriori sotto-sezioni.
1. Movimentazioni
(a) Carichi
(b) Ricette
2. Archivi
(a) Clienti
(b) Automezzi
(c) Vettori
(d) Destinazione
(e) Caricata per
(f ) Causali
(g) Prodotti
(h) Progetti ID
(i) Ordini ID
(j) Targets
(k) Ricette
3. Congurazione
(a) Dati impianto
(b) Sistema
i. Pannello di controllo
ii. Preferenze
(c) Attrezzi
(d) Caricato da
4. Trasferimento
CAPITOLO 4.
ANALISI DEI REQUISITI E DELL'ARCHITETTURA
39
5. Codice autista
6. Chiama helper 21
7. ipot
8. Delivery Docket
4.4
Analisi architetturale
Il sistema è stato suddiviso in 4 componenti:
Figura 4.2: Diagramma delle componenti
E' evidente dalle dipendenze del diagramma come il sistema sia composto di
3 layer (Backend, Register + PMS, GUI).
Laddove le componenti GUI e Backend si spiegano da sole, la componente
PMS (abbreviazione di Payload Management System), si occupa di astrarre la
gestione delle periferiche dedicate al trasferimento dati, in modo da facilitarne la
portabilità e l'estensibilità, mentre la componente
Register si occupa di astrarre
il supporto su cui memorizzare i dati che, nel nostro caso, era un database.
4.5
Pianicazione
Lo sviluppo è stato strutturato in 4 incrementi, con l'ultimo incremento dedicato esclusivamente allo sviluppo di funzionalità non obbligatorie, e quindi
considerato opzionale.
Segue la pianicazione degli incrementi.
CAPITOLO 4.
ANALISI DEI REQUISITI E DELL'ARCHITETTURA
40
4.5.1 Incremento n. 1
Il Sistema permette di:
•
Gestire gli Archivi {RF2}
•
Scambiare i dati in ingresso e in uscita tramite ikey reader (solo su
Windows) {RF5 (parziale)}
•
Eettuare tali operazioni attraverso un'interfaccia graca primitiva {RNF1.6;
RNF1.8 (parziali)}
Figura 4.3: Relazioni tra le entità in Archivi e Movimentazioni.
Le linee solide indicano una relazione stretta, basata sul valore di un campo
numerico, mentre le linee tratteggiate indicano una relazione più rilassata basata
sul valore di un campo stringa.
La scelta di gestire per primi gli
Archivi
è dovuta al fatto che essi sono
richiesti dalla parte di interfaccia relativa alle Movimentazioni (anche se, come è possibile vedere in gura 4.3, le relazioni non sono tali da imporre tale
scelta a livello di
Backend).
Considerando poi la bassa priorità della gestione
CAPITOLO 4.
della
ANALISI DEI REQUISITI E DELL'ARCHITETTURA
41
Congurazione di helper21, non erano disponibili molte alternative per
PMS.
iniziare ad implementare la componente
Per quanto riguarda la scelta di supportare ikey reader da subito anzichè il
trasferimento tramite GSM o radiofrequenza, che avrebbero avuto la precedenza
in un'ottica di minimizzazione dei rischi, è data dal fatto che le periferiche GSM
e RF permettono solo il trasferimento delle
Movimentazioni,
e quindi era
necessario aspettare che il supporto alla gestione di queste venisse introdotto
nel Backend.
In aggiunta, si è deciso di sviluppare l'interfaccia graca da subito, in quanto non c'erano motivazioni particolari per credere che un'interfaccia testuale
potesse rivelarsi utile, anzi avrebbe contribuito solo ad un allungamento dei
tempi, soprattutto considerando che
Glade ha dimostrato di poter permettere
lo sviluppo di interfacce grache in modo molto rapido.
4.5.2 Incremento n.2
Il Sistema permette di:
•
Gestire le Movimentazioni {RF1}
•
Essere congurato {RF4}
•
Scambiare dati attraverso GSM e radiofrequenza {RF5}
•
Eettuare tali operazioni attraverso un'interfaccia graca primitiva {RNF1.5;
RNF1.9; RNF1.10; RNF1.11 (parziali)}
Nessuna logica particolare è stata usata nell'assegnazione dei requisiti per que-
Movimentazioni, che
Congurazione, e di implementa-
sto incremento, a parte il fatto di gestire da subito le
erano un'area più prioritaria rispetto alla
re il supporto per il trasferimento tramite GSM e radiofrequenza il più presto
possibile, considerando l'impossibilità di farlo nel primo incremento.
4.5.3 Incremento n.3
Il Sistema permette di:
•
Gestire la congurazione {RF3}
•
Scrivere il codice autista su ikey (solo su Windows) {RF6}
•
Eettuare tali operazioni attraverso un'interfaccia graca migliorata {RNF1
(parziale)}
In questo incremento sono stati assegnati dei requisiti per far sì che la ripartizione del lavoro tra gli incrementi fosse abbastanza uniforme, in associazione al
requisito che l'interfaccia graca fosse di un buon livello qualitativo.
Il prodotto risultante da questo incremento presenta tutte le funzionalità di
base dell'Originale su Windows, mentre sulle altre piattaforme, manca solo del
supporto per il trasferimento tramite ikey.
CAPITOLO 4.
ANALISI DEI REQUISITI E DELL'ARCHITETTURA
42
4.5.4 Incremento n.4
Il sistema soddisfa tutti i requisiti
deve, dovrebbe, e alcuni di quelli vorrebbe
individuati nell'Analisi dei Requisiti.
Nel dettaglio il Sistema permette di:
•
Utilizzare ikey reader su Linux {RNF3}
•
Incrementare la produttività degli utenti rispetto a ipot OS4, laddove
possibile {RNF4 (parziale)}
•
Eettuare tali operazioni attraverso un'interfaccia graca assimilabile a
quella di ipot {RNF1}
Come spiegato precedentemente, i requisiti per questo incremento sono quelli
non obbligatori e/o quelli che si prevedeva fossero estremamente dispendiosi in
termini di tempo (vedi
RNF3).
Il prodotto risultante da questo incremento poteva considerarsi superiore
all'Originale sotto molti aspetti, e infatti rappresentava un traguardo tanto
ambizioso quanto dicile da raggiungere.
Capitolo 5
Sviluppo incrementale
Lo sviluppo è avvenuto in 3 incrementi, come pianicato. Il quarto non è stato
realizzabile nel tempo a disposizione.
Praticamente tutta l'architettura del sistema è stata denita nel primo incremento, mentre negli altri si è solo provveduto ad espanderla con nuove entità
e ad eettuare modiche a quelle già presenti per permetterne l'integrazione.
Al termine dello sviluppo è stato nalizzato il sistema di
deployment
e
quindi il tutto è stato validato dal Tutore.
5.1
Incremento n. 1
5.1.1 Progettazione
Per implementare le componenti
ster
PMS (Payload Management System) e Regi-
dell'architettura individuata nella fase di analisi architetturale, si è fatto
ricorso ai pattern Factory e Singleton.
43
CAPITOLO 5.
44
SVILUPPO INCREMENTALE
Figura 5.1: Implementazione della componente
PMS
CAPITOLO 5.
45
SVILUPPO INCREMENTALE
Figura 5.2: Implementazione della componente
Register
Per massimizzare l'estensibilità e per mantenere il codice compatto, è stata
ideata un'infrastruttura che attraverso un'astrazione dei metadati del database
permettesse con lo stesso codice di lettura e scrittura di leggere e scrivere su
qualsiasi tabella.
CAPITOLO 5.
46
SVILUPPO INCREMENTALE
Figura 5.3: Architettura dei metadati
5.1.2 Sviluppo
La prima cosa che è stata fatta per assicurare la portabilità è stata la denizione
typedef
di alias (
in C++) per i tipi basati sulla loro dimensione (ad esempio:
int8, uint32...). Ma dato che il C++ non dà garanzie sulla dimensione dei tipi,
è stato aggiunto un controllo a compile-time sulla dimensione dei tipi attraverso
l'utilizzo di template di classe specializzati in modo da causare errori di link nel
caso il controllo non desse l'esito sperato. Un esempio:
template<bool correct>
struct __cause_undefined_refence_on_wrong_type_size
{
explicit __cause_undefined_refence_on_wrong_type_size(int make_happy_gcc)
{
}
};
template<>
struct __cause_undefined_refence_on_wrong_type_size<false>
{
explicit __cause_undefined_refence_on_wrong_type_size(int make_happy_gcc);
};
const __cause_undefined_refence_on_wrong_type_size<sizeof(uint8) == 1> __check_uint8(0);
Dopodichè è stato possibile passare allo sviluppo in modo Agile delle porzioni
di
Backend, PMS
e
Register
previste per questo incremento.
Allo stesso
tempo sono stati sviluppati dei test per vericarne il corretto funzionamento,
grazie a questi è stato possibile ottenere un feedback immediato a proposito di
alcuni errori di design, il più grave dei quali è stata la decisione di rappresentare
campi strutturati come biteld nel database attraverso l'aggregazione di oggetti
di tipo
BoolField
(astrazione di un singolo valore booleano), anzichè usare
direttamente un oggetto
BitField, come poi è stato fatto nella correzione.
CAPITOLO 5.
47
SVILUPPO INCREMENTALE
Figura 5.4: Architettura delle sezioni
Lo sviluppo della GUI non è stato semplice da implementare dal punto di
vista della logica di funzionamento, visto che si è deciso, ragionevolmente, di
non realizzare una classe per la gestione di ogni sezione visualizzata sul frame
R, visto che molte di esse avevano la stessa identica logica di funzionamento.
In questi casi è stata invece realizzata una classe per ogni tipologia di sezione,
utilizzando opportunamente i metadati memorizzati negli oggetti (gli stessi
utilizzati nelle operazioni di scrittura e lettura su
Register).
Ciò ha comportato
la necessità di una qualche convenzione nel nome dei widget presenti nel le
.glade (similmente a come è stato eettuato per le combo box nel prototipo
descritto nella sezione 3.4 a pagina 31).
Dallo stesso prototipo è stata anche copiata la convenzione per il nome dei
widget di sezione, e del loro padre.
CAPITOLO 5.
SVILUPPO INCREMENTALE
48
Figura 5.5: Una porzione del widget tree che illustra le convenzioni usate per
il nome dei widget
5.1.3 Verica
I seguenti test sono stati eettuati, come documentato sul Piano di Test:
CAPITOLO 5.
49
SVILUPPO INCREMENTALE
1. Trasferimento tramite ikey di dati binari:
successo
2. Trasferimento tramite ikey di dati strutturati:
3. Scrittura/lettura con DBRegister:
successo
successo
L'esecuzione periodica dei test e l'aggiornamento continuo degli stessi per permettere la verica delle nuove funzionalità introdotte nel Sistema ha fatto sì che
tutti i bug più gravi siano stati risolti prima del processo di verica, che così è
stato breve.
In aggiunta, a seguito di una dimostrazione pratica, il Tutore ha espresso
il consenso per il proseguimento dello sviluppo per le funzionalità previste nel
prossimo incremento.
5.1.4 Conclusioni
La dimensione e la complessità dell'incremento si sono rivelate superiori alle
aspettative.
La realizzazione ha comportato 17 giorni lavorativi, contro i 7
pianicati. Perciò, alla ne dell'incremento è stata aggiornata la pianicazione
in modo da renderla più conservativa, anche se si riteneva improbabile che gli
incrementi successivi potessero richiedere così tanto tempo, considerando che
gran parte dell'architettura era stata sviluppata in questo incremento.
5.2
Incremento n.2
5.2.1 Progettazione
Nessuna modica strutturale di rilievo è stata introdotta nell'archittettura, si è
semplicemente provveduto ad espandere quella presente.
CAPITOLO 5.
50
SVILUPPO INCREMENTALE
Figura 5.6: Modiche di rilievo apportate alla componente
Figura 5.7: Aggiunte di rilievo al
Backend
PMS
CAPITOLO 5.
SVILUPPO INCREMENTALE
51
5.2.2 Sviluppo
Movimentazioni: ciò è stato fatto attraverso l'aggiunta delle classi LoadingMovement, BlendMovement e Movements. Quindi si è provveduto ad aggiornare
DBRegister e Ireader4 per supportare queste nuove entità.
Per prima cosa si è provveduto ad espandere il Backend per supportare le
Prima di procedere alla realizzazione della parte di interfaccia, è stato fattorizzato del codice in
NotebookSection che si occupava della gestione delle
DBCombo, in modo da unicare la
Gtk::ComboBoxEntry per creare la classe
gestione di tutte le combo box in un'unica classe. A questa classe sono state
poi aggiunte delle funzionalità per permettere di utilizzarla anche con widget
che non aderivano alle convenzioni denite nel primo incremento. Come valore
aggiunto, la fattorizzazione di quel codice ha comportato la riduzione di circa
300 righe della dimensione di
NotebookSection (che era di circa 1000 righe).
Figura 5.8: Sezioni aggiunte
Successivamente si è passati alla realizzazione del codice per la comunicazione
RF e GSM. Un prerequisito essenziale per tale funzionalità consisteva nella
capacità di comunicare in modo portabile con le porte seriali del PC. Purtroppo,
la ricerca di una libreria portabile non ha avuto successo, quindi ci si è visti
costretti a scrivere due versioni (una per Windows e una per Linux) del codice
più a basso livello utilizzando le API native, con la scelta della versione adatta
per la piattaforma corrente eettuata tramite compilazione condizionale.
La
portabilità di questa soluzione è limitata a Windows e Linux, mentre altri sistemi
POSIX sarebbero supportabili attraverso semplici modiche al codice.
Una volta realizzata l'infrastruttura per la comunicazione seriale, è stato
necessario ideare un metodo per gestire le trasmissioni da parte di helper21 che
possono avvenire in qualsiasi momento.
La soluzione ideale sarebbe stata la
realizzazione di un thread dedicato alla ricezione, ma per evitare le complessità
introdotte dai thread si è deciso di tentare prima una strada basata sull'utilizzo
delle
idle callback di GTK, funzioni che vengono chiamate quando l'interfaccia
timeout sulle operazioni di lettura da porta
graca è inattiva, associate a un
CAPITOLO 5.
52
SVILUPPO INCREMENTALE
seriale in modo da rendere le chiamate non bloccanti. Quest'ultima strategia
ha dimostrato di funzionare piuttosto bene e, associata all'utilizzo del pattern
Observer per la notica dell'arrivo dei dati rappresenta una soluzione elegante
ed estensibile. L'unico suo difetto è la dipendenza dal fatto che il Sistema entri
nel loop Main di GTK visto che, in caso contrario, le idle callback non vengono
mai chiamate.
5.2.3 Verica
Oltre ai test del primo incremento, che sono stati aggiornati per vericare le nuove funzionalità introdotte, è stato aggiunto un test per vericare che il supporto
alla comunicazione RF e GSM fosse corretto.
I risultati:
1. Trasferimento tramite ikey di dati binari:
successo
2. Trasferimento tramite ikey di dati strutturati:
3. Scrittura/lettura con DBRegister:
4. Trasferimento tramite RF e GSM:
successo
successo
successo parziale, infatti è stato pos-
sibile provare solo le periferiche RF, visto che le periferiche GSM non
funzionavano correttamente
Come spiegato nella descrizione della fase di verica del precedente incremento,
i test sono stati eseguiti periodicamente e aggiornati a mano a mano che il codice
è stato scritto.
5.2.4 Conclusioni
Il piano di progetto è stato rispettato per questo incremento, ed è stato necessario anche meno tempo del previsto. Comunque, la data di ne del prossimo
incremento non è stata spostata, infatti il tempo eventualmente risparmiato sarebbe tranquillamente investibile nel terzo requisito, cioè il miglioramento della
GUI.
5.3
Incremento n.3
5.3.1 Progettazione
Nessuna modica strutturale di rilievo è stata introdotta nell'archittettura, si è
semplicemente provveduto ad espandere quella presente.
CAPITOLO 5.
53
SVILUPPO INCREMENTALE
Figura 5.9: Aggiunte di rilievo al
Backend
5.3.2 Sviluppo
congurazioni: ciò è stato fatto attraverso l'aggiunta delle classi SystemData, Attachment e Conguration. Quindi si è provveduto ad aggiornare
DBRegister e Ireader4 per supportare queste nuove entità.
Per prima cosa si è provveduto ad espandere il Backend per supportare le
La realizzazione dell'interfaccia graca per la gestione delle congurazioni
si è rivelata dicile in quanto l'organizzazione dell'interfaccia dell'Originale in
quest'area appariva piuttosto diversamente da quello che si era visto in precedenza.
E anche se durante la fase di analisi dei requisiti questa dierenza
non era passata inosservata, non si riteneva sarebbe stata problematica la sua
realizzazione.
Figura 5.10: Sezioni aggiunte
La problematica è stata risolta scrivendo da zero il codice di gran parte
delle sezioni, che si sono rivelate semplici da realizzare in quanto le entità da
CAPITOLO 5.
54
SVILUPPO INCREMENTALE
gestire erano singole (nessuna necessità di gestire lo spostamento tra i record e la
modica o eliminazione degli stessi), e i campi erano principalmente costituiti da
enumerazioni. Quindi anche le necessità di accedere alla componente Register
sono state molto ridotte.
La gestione degli
attrezzi ha invece comportato maggiori dicoltà in quan-
to, nonostante le similitudini con le altre sezioni per la modica di entità multiple, la necessità di ltrare il contenuto della relativa tabella per visualizzare
solo le entità associate al
codice macchina scelto ha comportato la necessità
re-ingegnerizzazione di NotebookSection per
di scegliere tra 3 possibilità:
renderla più essibile; scrittura di una classe ad-hoc utilizzando in gran parte
codice copiato da NotebookSection; ereditare da NotebookSection reimple-
mentando metodi critici che inizialmente non erano stati concepiti per essere
rideniti. La prima scelta è stata scartata per motivi di disponibilità e priorità
temporali, la seconda perchè una tale duplicazione di codice non sarebbe stata
giusticabile alla luce delle scarse dierenze nelle funzionalità della nuova classe. Alla ne, è stato necessario aggiungere il marcatore
virtual soltanto a due
metodi:
•
update_models(): responsabile di aggiornare i modelli dei widget basati
sul paradigma model-view, nel nostro caso solo quello del TreeView, visto
che non sono utilizzate ComboBox nella modica degli attrezzi.
•
update_append_record():
segnala un errore nel caso in cui si tenti di
aggiungere attrezzi una volta raggiunto il numero massimo, che è 4, altrimenti chiama semplicemente il metodo della classe base.
Dal punto di vista del miglioramento della GUI (terzo requisito di incremento),
è stato risolto un malfunzionamento nel caricamento delle sezioni attivate in seguito al click su un'icona nella lista di sinistra. Poi si è fatto in modo di forzare
l'utilizzo del tema
Glossy P all'avvio, in quanto ci si è resi conto che la meto-
dologia utilizzata per realizzare l'interfaccia con Glade faceva adamento sulla
dimensione dei widget di quel tema. Alternativamente, sarebbe stato possibile
ristrutturare la GUI per farla funzionare con altri temi, ma ciò avrebbe richiesto
una considerevole quantità di tempo, quindi si trattava di un'attività al limite
realizzabile nel quarto incremento, come parte del requisito di miglioramento
della GUI.
Pochi giorni prima del termine della fase di sviluppo, il Tutore ha svolto una
breve fase di valutazione del sistema, il cui riscontro è stato sostanzialmente
positivo, sono solo state sollevate un paio di imperfezioni nella disposizione
dei widget e un'imprecisione nel salvataggio dei record modicati che causava
occasionalmente la perdita dei dati immessi, la risoluzione delle quali ha richiesto
meno di una giornata lavorativa.
5.3.3 Verica
Sono stati ripetuti tutti i test del secondo incremento, che sono stati naturalmente aggiornati per vericare le nuove funzionalità introdotte.
I risultati:
successo
Trasferimento tramite ikey di dati strutturati: successo
1. Trasferimento tramite ikey di dati binari:
2.
CAPITOLO 5.
55
SVILUPPO INCREMENTALE
3. Scrittura/lettura con DBRegister:
4. Trasferimento tramite RF e GSM:
successo
successo parziale, infatti è stato pos-
sibile provare solo le periferiche RF, visto che le periferiche GSM non
funzionavano correttamente
Come spiegato nella descrizione della fase di verica del precedente incremento,
i test sono stati eseguiti periodicamente e aggiornati a mano a mano che il codice
è stato scritto.
5.3.4 Conclusioni
Il piano di progetto è stato rispettato per questo incremento, ed è stato necessario esattamente il tempo previsto. Anche se questo risultato è stato possibile
grazie al sacricio del requisito di miglioramento della GUI. Infatti, come è
possibile leggere nella descrizione della fase di sviluppo, le migliorie apportate
sono state poche, e consistenti soprattutto nella risoluzione di bug.
5.4
Deployment e Validazione
Per prima cosa è stata completata la
localizzazione
del codice, che era già
stata parzialmente realizzata marcando le stringhe utilizzate nel codice in modo
da renderle compatibili con
gettext.
Quindi si è proceduti alla realizzazione dei
le .PO contenenti le traduzioni utilizzando stringhe memorizzate sul database
dell'Originale. Non è stato poi molto dicile fare in modo che lo script di build
compilasse questi le nel formato ottimizzato necessario a run-time dal sistema
di localizzazione.
Dopodichè è stato perfezionato il sistema di
installazione su Linux, questo
ha comportato la scelta di utlizzare uno script di shell per lo scopo, viste le
dicoltà incontrate nell'utlizzo del sistema di installazione fornito da
SCons.
Tale script copiava l'eseguibile e gli altri le richiesti da esso in un percorso
a scelta, seguendo la struttura standard dei sistemi Unix (binari in bin/, dati
accessori in share/ipot/) e aggiungeva un DSN globale per fare in modo che
venisse utilizzato lo stesso le di database da tutti gli utenti (vista la possibilità
che il le di database venisse installato in un percorso non scrivibile da utenti
comuni, sono stati poi applicati sullo stesso permessi tali da permettere la lettura
e la scrittura a tutti gli utenti, ossia -rw-rw-rw-).
Terminata la fase di deployment su Linux, ci si è occupati di realizzare
quella per Windows:
il binario era semplicemente composto da una cartella
posizionabile ovunque nel le system (meglio se in posizioni non scrivibili dagli
utenti comuni).
Per quanto riguarda il database, non essendo stato possibile
trovare comandi prompt per gestire i DSN, è stata sviluppata una soluzione
basata sulla fabbricazione di un le .REG contente le chiavi di registro necessarie
all'aggiunta del DSN. Se all'avvio dell'eseguibile il DSN non veniva trovato, si
procedeva all'installazione del DSN (eseguendo il le .REG tramite la funzione
standard
system)
e del le di database, in modo che lo stesso database fosse
utilizzabile da tutti gli utenti.
La
validazione è stata eettuata dal Tutore, sostanzialmente si è trattato
di vericare che il comportamento dell'interfaccia fosse lo stesso dell'Originale e
di capire la struttura e l'organizzazione del sorgente e dei documenti. Oltretutto
CAPITOLO 5.
SVILUPPO INCREMENTALE
56
si è vericato che il sistema di deployment si comportasse correttamente sia su
Windows che su Linux.
Capitolo 6
Conclusione
Sostanzialmente, la conversione ha avuto successo, anche se si è stati costretti
ad escludere alcune funzionalità per motivi temporali e tecnologici.
All'azienda
1 è stato comunque lasciato un prodotto precisamente documen-
tato e caratterizzato da un buon livello di qualità interna (come illustra la tabella
6.1), così da rendere il più agevole possibile l'aggiunta di nuove funzionalità e
la manutenzione.
Metrica
Originale Risultante
Linee logiche di codice (LLOC)
27233
9954
Linee logiche di commento (COM)
7487
2021
Procedure
652
672
Moduli
-
82
Media di LLOC per Metodo
42.7
14.8
Media di LLOC per Modulo
-
121.4
Densità dei commenti (COM/LLOC)
31%
20%
Media di COM per Modulo
-
24.6
Complessità Ciclomatica (CC) per Procedura
8.5
1.4
CC per Modulo
-
11.9
Backend + Register)
PMS)
CC per Modulo (
CC per Modulo (
-
7.3
-
37.8
Media di Fan-in per Procedura
1.1
-
Media di Fan-in per Modulo
-
3.1
Tabella 6.1:
Alcuni risultati di analisi statica ottenuti con
lyzer (http://www.aivosto.com/project/project.html)
sourceforge.net/projects/cccc/).
e
Project Anacccc (http://
Considerando che l'Originale è basato su procedure, mentre il Risultante è basato su classi, alcune metriche sono state adattate per rendere possibile un
confronto, in tal caso i valori sono misurati su tutti metodi di classe e globali.
Notare come molti parametri siano migliori nella conversione, la dierenza
1 Abitat
SIT di Pojana Maggiore (VI)
57
CAPITOLO 6.
58
CONCLUSIONE
nella quantità di commenti è principalmente imputabile al fatto che nell'Originale molti commenti sono usati per escludere codice dalla compilazione, mentre
l'alta complessità ciclomatica della componente
PMS è dovuta al fatto che in
quella componente gran parte del codice è a basso livello e anche perchè alcune
classi al suo interno sono piuttosto corpose. Proprio per quanto riguarda la complessità ciclomatica, è opportuno però notare come i valori siano dicilmente
comparabili in quanto non è detto che i due strumenti utilizzati si basino sullo
stesso metodo per calcolarla, in più
cccc calcola la complessità ciclomatica per
ogni modulo sommando quella dei suoi metodi, quindi non è ragionevole comparare un valore di complessità mediato sulle Procedure con uno mediato sui
Moduli. Nonostante la dierenza sembri esagerata, il valore di complessità più
adatto ad essere comparato è quello mediato sulle Procedure/Metodi.
Glossario
Archivi
Database mantenuto da helper21 contente dati relativi a clienti, vet-
tori, prodotti ecc. . .
Codice macchina
Una breve stringa che identica una unità helper21, utile
nel caso ipot venga usato con più helper21 contemporaneamente
Congurazione
L'insieme dei parametri di funzionamento di helper21
Host controller
L'interfaccia hardware tra il dispositivo USB e il sistema
operativo, anche chiamata con l'acronimo HCI (Host Controller Interface)
Linux
Abbreviazione di GNU/Linux, il popolare sistema operativo Open Sour-
ce
Movimentazioni
Operazioni di carico costituite da una certa quantità di uno
o più prodotti
Originale
PMS
Abbreviazione di ipot OS4, oggetto dell'attività di conversione
Abbreviazione di Payload Management System, che nel nostro caso iden-
tica un sistema sviluppato da VEI (http://www.veigroup.com) che si
occupa di gestire dati di carico
Risultante
Abbreviazione di ipot OS5, prodotto risultante dell'attività di
conversione
Tutore
Titolo usato per riferirsi a Nicola Zanchin, programmatore dell'azien-
da Abitat SIT di Pojana Maggiore (VI) che ha assistito l'Autore nella
realizzazione del progetto
59
Bibliograa
[CY4604]
[CY7C64713]
[Wer06]
Cypress,
USB Developer's uStudio
com/design/RD1048)
(http://www.cypress.
CY7C64713
product
description
(http:
//www.cypress.com/portal/server.pt?space=
CommunityPage&control=SetCommunity&CommunityID=
209&PageID=259&fid=13&rpn=CY7C64713)
Cypress,
Christian
Werner,
SQLite
ch-werner.de/sqliteodbc/)
ODBC
Driver
(http://www.
[FREEODBC]
The freeodbc++ project (http://libodbcxx.sourceforge.
[Sto111406]
Cypress
net/)
USB
windows.wine
driver
emulation,
newsgroup
comp.emulators.ms-
(http://groups.google.
com/group/comp.emulators.ms-windows.wine/msg/
357d8e6708c21658)
[MOE06]
techieMoe, how does Wine work?,
LINUX FORUMS (http:
//www.linuxforums.org/forum/393156-post2.html)
mailing
list
(https://lists.sourceforge.net/
lists/listinfo/cyport-users)
[CYPORT-ML] cyport
[USBDEV-ML] Win32:
Out
of
memory,
Linux:
inappropriate
Getting rmware from a device/driver (was Re:
ioctl
e
Win32:
Out of memory, Linux:
inappropriate ioctl),
libusbdevel mailing list (https://lists.sourceforge.net/lists/
listinfo/libusb-devel)
[KR-HAR04]
Greg Kroah-Hartman, Writing a Real Driver In User Space,
Linux Journal (http://www.linuxjournal.com/article/
7466)
[EZ-LINUX]
[EZ-DEVKIT]
[GLOSSY]
Linux-USB, EZ-USB on Linux (http://www.linux-usb.org/
ezusb/)
Cypress, AN2131-DK001 EZ-USB Development Kit (
//www.cypress.com/design/DK10029)
http:
m5brane, Glossy P theme (http://art.gnome.org/themes/
gtk2/571)
60
61
BIBLIOGRAFIA
[EZ-REF]
Cypress, EZ-USB FX Technical Reference Manual (incluso con
[EZ-DEVKIT])
[VEI-FW]
[LAR05]
VEI, Interfaccia tra ipot (appl. VEI su PC) e FW USB
Craig Larman, APPLYING UML AND PATTERNS: An Intro-
duction to Object-Oriented Analysis and Design and Iterative
Development,
Prentice Hall