150875
numer indeksu
Grzegorz Graczyk
imi i nazwisko
151021
numer indeksu
Paweł Tarasiuk
imi i nazwisko
Data 2010-03-03
Kierunek Informatyka Rok akademicki 2009/10
Semestr 4
Grupa dziekańska 2
Laboratorium telekomunikacji
Zadanie 3
Opis programu
Protokół XModem cechuje się prostotą implementacji, dzięki czemu może być używany wszę- dzie tam, gdzie bardziej zaawansowane protokoły nie są dostępne. Także przygotowany przez nas w języku C++ program jest bardzo prosty - pozwala on odbierać oraz wysyłać pliki za pomocą tego protokołu. Do kompilacji programu wykorzystujemy narzędzia z zestawu MinGW, pod systemem Windows. Wydzieliliśmy z naszego kodu funkcje odpowiedzialne za nawiązywanie połączenia za pośrednictwem portu szeregowego i umieściliśmy je w osobnym pliku sock.h - wy- nika to z logiki programu, a ponadto przygotowany przez nas nagłówek może się nam przydać przy rozwiązywaniu innych zadań laboratoryjnych. Program przyjmuje prosty, jednoznakowy argument pozwalający decydować, czy pliki będą wysyłane, czy odbierane, oraz argumenty po- zwalające wybrać port COM oraz plik do wysłania bądź nazwę pod którą zostanie zapisanu odebrany plik. Opcjonalny argument pozwala wukorzystać metodę CRC do sprawdzania po- prawności przesłanych danych. Naszym założeniem było stworzenie możliwie prostego (zarówno w swojej strukturze jak i w użyciu) i minimalistycznego kodu, a także oszczędność zasobów systemowych. Głółnym naszym celem było uzyskania kompatybilności z istniejącymi imple- mentacjami. Korzystamy z paradygmatów programowania proceduralnego, realizując elementy rozwiązania problemu poprzez określone przez nas funkcje.
Poniżej zamieszczamy całość kodu źródłowego przygotowanego przez nas programu.
Plik sock.h
#i n c l u d e <windows . h>
HANDLE hComm ; BOOL bPortReady ; DCB dcb ;
COMMTIMEOUTS CommTimeouts ; i n t BaudRate = 5 7 6 0 0 ;
v o i d I n i t (c h a r ∗ComPortName /∗ , i n t BaudRate ∗/ ) {
hComm = C r e a t e F i l e ( ComPortName , GENERIC READ | GENERIC WRITE, 0 , // e x c l u s i v e a c c e s s NULL, // no s e c u r i t y
OPEN EXISTING , 0 , // no o v e r l a p p e d I /O NULL // n u l l t e m p l a t e
) ;
bPortReady = SetupComm (hComm, 1 , 1 2 8 ) ; // s e t b u f f e r s i z e s
bPortReady = GetCommState (hComm, &dcb ) ;
dcb . BaudRate = BaudRate ; dcb . B y t e S i z e = 8 ;
dcb . P a r i t y = NOPARITY; //EVENPARITY ; dcb . S t o p B i t s = ONESTOPBIT ;
dcb . f A b o r t O n E r r o r = TRUE;
dcb . fOutX = FALSE ; // XON/XOFF o f f f o r t r a n s m i t dcb . f I n X = FALSE ; // XON/XOFF o f f f o r r e c e i v e
dcb . fOutxCtsFlow = FALSE ; // t u r n on CTS f l o w c o n t r o l dcb . f R t s C o n t r o l = RTS CONTROL HANDSHAKE;
dcb . fOutxDsrFlow = FALSE ; // t u r n on DSR f l o w c o n t r o l dcb . f D t r C o n t r o l = DTR CONTROL ENABLE ;
dcb . f D t r C o n t r o l = DTR CONTROL DISABLE ; dcb . f D t r C o n t r o l = DTR CONTROL HANDSHAKE;
bPortReady = SetCommState (hComm, &dcb ) ; // Communication t i m e o u t s a r e o p t i o n a l
/∗ bPortReady = GetCommTimeouts (hComm, &CommTimeouts ) ;
CommTimeouts . R e a d I n t e r v a l T i m e o u t = MAXDWORD;
CommTimeouts . ReadTotalTimeoutConstant = 1 ;
CommTimeouts . R e a d T o t a l T i m e o u t M u l t i p l i e r = MAXDWORD;
CommTimeouts . W r i t e T o t a l T i m e o u t C o n s t a n t = 0 ; CommTimeouts . W r i t e T o t a l T i m e o u t M u l t i p l i e r = 0 ;
bPortReady = SetCommTimeouts (hComm, &CommTimeouts ) ; ∗/
}
v o i d Recv (c h a r ∗ r x c h a r , i n t l e n ) { DWORD p o s = 0 , num ;
w h i l e( p o s < l e n ) {
R e a d F i l e (hComm, r x c h a r + pos , l e n − pos , &num , NULL ) ; p o s += num ;
} }
v o i d Send (c h a r ∗ t x c h a r , i n t l e n ) { DWORD num ;
W r i t e F i l e (hComm, t x c h a r , l e n , &num , NULL ) ; }
Plik main.cpp
#i n c l u d e < s t d i o . h>
#i n c l u d e < s t d l i b . h>
#i n c l u d e < s t r i n g . h>
#i n c l u d e <i o s t r e a m >
#i n c l u d e ” s o c k . h”
//#i n c l u d e ” c r c . h”
#d e f i n e SOH 0 x1
#d e f i n e EOT 0 x4
#d e f i n e ACK 0 x6
#d e f i n e NAK 0 x15
#d e f i n e C ’C ’
#d e f i n e SUB 26 b o o l c r c ;
s h o r t i n t c r c 1 6 (c h a r ∗ f b u f ) {
i n t tmp = 0 , v a l = 0 x18005 << 1 5 ; f o r(i n t i = 0 ; i < 3 ; i ++)
tmp = tmp ∗ 256 + (u n s i g n e d c h a r) f b u f [ i ] ; tmp ∗= 2 5 6 ;
f o r(i n t i = 3 ; i < 1 3 4 ; i ++) { i f( i < 1 2 8 )
tmp += (u n s i g n e d c h a r) f b u f [ i ] ; f o r(i n t j = 0 ; j < 8 ; j ++) {
i f( tmp & ( 1 << 3 1 ) ) tmp ˆ= v a l ; tmp <<= 1 ; }
// p r i n t f (”[% x ] \ n ” , tmp ) ; }
r e t u r n tmp >> 1 6 ; }
c h a r ∗COM;
c h a r ∗ f i l e ; v o i d r e c v ( ) {
c h a r b u f [ 3 ] , f b u f [ 1 2 8 ] ;
I n i t (COM) ;
b u f [ 0 ] = c r c ? C : NAK;
Send ( buf , 1 ) ;
FILE ∗ f = f o p e n ( f i l e , ”wb”) ;
Recv ( buf , 1 ) ;
p r i n t f (”%d\n”, b u f [ 0 ] ) ; w h i l e(t r u e) {
u n s i g n e d s h o r t sum , sumc ; Recv ( b u f + 1 , 2 ) ;
Recv ( f b u f , 1 2 8 ) ;
sum = sumc = 0 ;
Recv ( (c h a r ∗ ) &sum , c r c ? 2 : 1 ) ;
i f( c r c )
sumc = c r c 1 6 ( f b u f ) ; e l s e {
f o r(i n t i = 0 ; i < 1 2 8 ; i ++)
sumc += (u n s i g n e d c h a r) f b u f [ i ] ; sumc %= 2 5 6 ;
}
// sumc = sum ;
p r i n t f (”%x %x %x \n”, sum , sumc ) ; // S l e e p ( 1 0 0 0 ) ;
i f( sum != sumc ) {
b u f [ 0 ] = NAK;
Send ( buf , 1 ) ; c o n t i n u e; }
b u f [ 0 ] = ACK;
Send ( buf , 1 ) ;
Recv ( buf , 1 ) ; i f( b u f [ 0 ] == EOT) {
u n s i g n e d c h a r l a s t = 1 2 7 ; w h i l e( f b u f [ l a s t ] == SUB)
l a s t −−;
f w r i t e ( f b u f , l a s t + 1 , 1 , f ) ; b r e a k;
}
f w r i t e ( f b u f , 1 2 8 , 1 , f ) ;
}
f c l o s e ( f ) ; b u f [ 0 ] = ACK;
Send ( buf , 1 ) ; }
v o i d s e n d ( ) {
c h a r b u f [ 3 ] , f b u f [ 1 2 8 ] ; I n i t (COM) ;
Recv ( buf , 1 ) ;
p r i n t f (”%d\n”, b u f [ 0 ] ) ; i f( b u f [ 0 ] == NAK)
c r c = f a l s e; e l s e i f( b u f [ 0 ] == C)
c r c = t r u e; e l s e
r e t u r n;
i n t no = 1 ;
FILE ∗ f = f o p e n ( f i l e , ” r b ”) ; f s e e k ( f , 0 , SEEK END ) ; i n t f s i z e = f t e l l ( f ) ; f s e e k ( f , 0 , SEEK SET ) ;
w h i l e( f t e l l ( f ) < f s i z e ) {
u n s i g n e d c h a r l e n = f r e a d ( f b u f , 1 , 1 2 8 , f ) ; f o r(i n t i = l e n ; i < 1 2 8 ; i ++)
f b u f [ i ] = SUB ; u n s i g n e d s h o r t sum = 0 ; sum = 0 ;
i f( c r c )
sum = c r c 1 6 ( f b u f ) ; e l s e {
f o r(i n t i = 0 ; i < 1 2 8 ; i ++) sum += (u n s i g n e d c h a r) f b u f [ i ] ; sum %= 2 5 6 ;
}
b u f [ 0 ] = SOH ; b u f [ 1 ] = no ; b u f [ 2 ] = 255 − no ;
Send ( buf , 3 ) ; Send ( f b u f , 1 2 8 ) ;
Send ( (c h a r ∗ ) &sum , c r c ? 2 : 1 ) ;
Recv ( buf , 1 ) ;
// p r i n t f (”[% d ] \ n ” , b u f [ 0 ] ) ; i f( b u f [ 0 ] == ACK)
no++;
e l s e
f s e e k ( f , −128 , SEEK CUR ) ; }
f c l o s e ( f ) ;
do {
b u f [ 0 ] = EOT;
Send ( buf , 1 ) ; Recv ( buf , 1 ) ; } w h i l e( b u f [ 0 ] != ACK) ; }
i n t main (i n t a r g c , c h a r ∗ a r g v [ ] ) { COM = a r g v [ 2 ] ;
f i l e = a r g v [ 3 ] ; i f( a r g c > 4 )
c r c = s t r c m p ( a r g v [ 4 ] , ”CRC”) ? f a l s e : t r u e; i f( s t r c m p ( a r g v [ 1 ] , ”R”) )
s e n d ( ) ; e l s e
r e c v ( ) ; }