You are on page 1of 136

Giao thc TCP/IP v Web server vi AVR

Xin cho tt c mi ngi.


Mnh tham gia din n kh lu ri nhng khng c ng gp g cho din n, m chm t
din n th kh nhiu. Hm nay thy cn rt lng tm qu nn lm 1 ci tut ng gp cho
TVN.
Mnh thy ti giao tip TCP/IP vi AVR v iu khin qua Internet c kh nhiu bn quan
tm, ti liu trn cc din n nc ngoi cng kh nhiu nhng cha c tut no c th v chi
tit, c bit l hng dn mi ngi c th t vit code c, ch khng phi copy code c
sn. V vy nn mnh li 1 project lm cch y kh lu ra lm c s cho tut ny.
Bi 1-Hardware:
Trong project ny mnh s dng mt con ENC28J60 ca Microchip giao tip Ethernet. Vi iu
khin th s dng Atmega32, c b nh RAM 2k, va dng (v 1 frame ethernet c chiu di
max 1500bytes).
Mi ngi c th mua 1 module pht trin Atmega32 + ENC28J60 ti TME
(ATMEGA32 - Ethernet board - TMe: Linh kien, Sensors, Kit Phat trien, Mach nap 8051, PIC,
AVR, ARM, EPROM, Flash...). Hay t build 1 mch theo s sau:

M t:
- Atmega32 giao tip vi ENC28J60 qua SPI (MOSI/MISO/SCK) ngoi ra cn c chn chn chip
CS (ni vi bt c IO no ca Atmega) v ngt INT (ni vo ngt ngoi VK).
- ENC28J60 dng ngun 3V3, do cn 1 IC n p 3V3. ENC28J60 cn 1 port RJ45 c tch hp
sn Transformer v LED.
- Thm MAX232 dng vo mc ch debug.

- Thm LCD v keypad (dng config hay hin th g sau ny). Nu khng cn c th b
ra.
Bi 2-C s giao thc v thit k lu d liu-To project trong AVR studio:
Chng giao thc TCP/IP:
Di y l m hnh chng giao thc TCP/IP

C th ha v lu d liu vo ra ca giao thc (p dng cho phn lp trnh)

Nh vy phn lp trnh s chia ra cc module sau:


- Module iu khin ENC28J60: nm trong file enc28j60.c v file header enc28j60.h, thm
file enc28j60conf.h lu cc config.
- Module giao thc Ethernet: gm cc file: ethernet.c v ethernet.h, thm file "packet.h"
khai bo cc cu trc gi tin s dng trong b giao thc TCP/IP.
- Module giao thc phn gii a ch Address Resolution Protocol, gm file arp.c v arp.h
- Module giao thc IP gm ip.c v ip.h
- Module giao thc cp pht a ch IP ng DHCP (Dynamic Host Configuration Protocol) gm
cc file dhcp.c v dhcp.h
- Module giao thc UDP gm cc file udp.c v udp.h
- Module giao thc TCP gm cc file tcp.c v tcp.h
- Module giao thc HTTP gm cc file http.c v http.h
- V mt s cc hm h tr khc (uart, timer,)
Ton b code vit trn AVR Studio, bin dch vi AVR-GCC
Ta to 1 project mi trong AVR studio:

Set thuc tnh cho project v chn CPU, chn tn s thch anh:

Sau khi to project, ta s c source file u tin l ntAVRnet.c.


M file ny, thm vo hm main, chng trnh chnh, ni dung hm ny s c vit cui cng

Code:
//---------------------------------------------------------------------------// Writen by NTTam - PTITHCM
//---------------------------------------------------------------------------#include <avr/io.h>
//---------------------------------------------------------------------------int
{

main()
return(0);

To thm file header cho n: ntAVRnet.h c ni dung:


Code:
//---------------------------------------------------------------------------// Writen by NTTam - PTITHCM
//---------------------------------------------------------------------------#ifndef NTAVRNET_H
#define NTAVRNET_H
#endif //NTAVRNET_H

File ny s dng cha cc define v thng tin config chung cho ton project
Bi 3:-Lp trnh iu khin ENC28J60:
Phn ny c tham kho cc project open source ca nc ngoi, thng tin v ti liu tham kho
s c nu c th cui tut
To cc file enc28j60.c, enc28j60.h v enc28j60conf.h. Add vo project
ENC28J60 c iu khin bi mt tp kh ln cc thanh ghi iu khin, d liu (frame
ehternet gi/nhn) c lu tr trn 1 buffer. Vic c/ghi vo cc thanh ghi iu khin cng
nh buffer d liu c thc hin qua giao tip SPI ti 1 a ch xc nh.
M file enc28j60.h, khai bo a ch cc thanh ghi vo file
Code:
//---------------------------------------------------------------------------// Writen by NTTam - PTITHCM
//---------------------------------------------------------------------------#ifndef ENC28J60_H
#define ENC28J60_H
// ENC28J60 Control Registers
// Control register definitions are a combination of address,
// bank number, and Ethernet/MAC/PHY indicator bits.
// - Register address
(bits 0-4)
// - Bank number
(bits 5-6)
// - MAC/PHY indicator
(bit 7)
#define ADDR_MASK
0x1F
#define BANK_MASK
0x60
#define SPRD_MASK
0x80
// All-bank registers
#define EIE
0x1B
#define EIR
0x1C
#define ESTAT
0x1D
#define ECON2
0x1E
#define ECON1
0x1F
// Bank 0 registers
#define ERDPTL
(0x00|0x00)

#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
// Bank
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
// Bank
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define

ERDPTH
(0x01|0x00)
EWRPTL
(0x02|0x00)
EWRPTH
(0x03|0x00)
ETXSTL
(0x04|0x00)
ETXSTH
(0x05|0x00)
ETXNDL
(0x06|0x00)
ETXNDH
(0x07|0x00)
ERXSTL
(0x08|0x00)
ERXSTH
(0x09|0x00)
ERXNDL
(0x0A|0x00)
ERXNDH
(0x0B|0x00)
ERXRDPTL (0x0C|0x00)
ERXRDPTH (0x0D|0x00)
ERXWRPTL (0x0E|0x00)
ERXWRPTH (0x0F|0x00)
EDMASTL
(0x10|0x00)
EDMASTH
(0x11|0x00)
EDMANDL
(0x12|0x00)
EDMANDH
(0x13|0x00)
EDMADSTL (0x14|0x00)
EDMADSTH (0x15|0x00)
EDMACSL
(0x16|0x00)
EDMACSH
(0x17|0x00)
1 registers
EHT0
(0x00|0x20)
EHT1
(0x01|0x20)
EHT2
(0x02|0x20)
EHT3
(0x03|0x20)
EHT4
(0x04|0x20)
EHT5
(0x05|0x20)
EHT6
(0x06|0x20)
EHT7
(0x07|0x20)
EPMM0
(0x08|0x20)
EPMM1
(0x09|0x20)
EPMM2
(0x0A|0x20)
EPMM3
(0x0B|0x20)
EPMM4
(0x0C|0x20)
EPMM5
(0x0D|0x20)
EPMM6
(0x0E|0x20)
EPMM7
(0x0F|0x20)
EPMCSL
(0x10|0x20)
EPMCSH
(0x11|0x20)
EPMOL
(0x14|0x20)
EPMOH
(0x15|0x20)
EWOLIE
(0x16|0x20)
EWOLIR
(0x17|0x20)
ERXFCON
(0x18|0x20)
EPKTCNT
(0x19|0x20)
2 registers
MACON1
(0x00|0x40|0x80)
MACON2
(0x01|0x40|0x80)
MACON3
(0x02|0x40|0x80)
MACON4
(0x03|0x40|0x80)
MABBIPG
(0x04|0x40|0x80)
MAIPGL
(0x06|0x40|0x80)
MAIPGH
(0x07|0x40|0x80)
MACLCON1 (0x08|0x40|0x80)
MACLCON2 (0x09|0x40|0x80)
MAMXFLL
(0x0A|0x40|0x80)
MAMXFLH
(0x0B|0x40|0x80)
MAPHSUP
(0x0D|0x40|0x80)
MICON
(0x11|0x40|0x80)
MICMD
(0x12|0x40|0x80)
MIREGADR (0x14|0x40|0x80)

#define MIWRL
#define MIWRH
#define MIRDL
#define MIRDH
// Bank 3 registers
#define MAADR1
#define MAADR0
#define MAADR3
#define MAADR2
#define MAADR5
#define MAADR4
#define EBSTSD
#define EBSTCON
#define EBSTCSL
#define EBSTCSH
#define MISTAT
#define EREVID
#define ECOCON
#define EFLOCON
#define EPAUSL
#define EPAUSH
// PHY registers
#define PHCON1
#define PHSTAT1
#define PHHID1
#define PHHID2
#define PHCON2
#define PHSTAT2
#define PHIE
#define PHIR
#define PHLCON

(0x16|0x40|0x80)
(0x17|0x40|0x80)
(0x18|0x40|0x80)
(0x19|0x40|0x80)
(0x00|0x60|0x80)
(0x01|0x60|0x80)
(0x02|0x60|0x80)
(0x03|0x60|0x80)
(0x04|0x60|0x80)
(0x05|0x60|0x80)
(0x06|0x60)
(0x07|0x60)
(0x08|0x60)
(0x09|0x60)
(0x0A|0x60|0x80)
(0x12|0x60)
(0x15|0x60)
(0x17|0x60)
(0x18|0x60)
(0x19|0x60)
0x00
0x01
0x02
0x03
0x10
0x11
0x12
0x13
0x14

// ENC28J60 EIE Register Bit Definitions


#define EIE_INTIE
0x80
#define EIE_PKTIE
0x40
#define EIE_DMAIE
0x20
#define EIE_LINKIE
0x10
#define EIE_TXIE
0x08
#define EIE_WOLIE
0x04
#define EIE_TXERIE
0x02
#define EIE_RXERIE
0x01
// ENC28J60 EIR Register Bit Definitions
#define EIR_PKTIF
0x40
#define EIR_DMAIF
0x20
#define EIR_LINKIF
0x10
#define EIR_TXIF
0x08
#define EIR_WOLIF
0x04
#define EIR_TXERIF
0x02
#define EIR_RXERIF
0x01
// ENC28J60 ESTAT Register Bit Definitions
#define ESTAT_INT
0x80
#define ESTAT_LATECOL
0x10
#define ESTAT_RXBUSY
0x04
#define ESTAT_TXABRT
0x02
#define ESTAT_CLKRDY
0x01
// ENC28J60 ECON2 Register Bit Definitions
#define ECON2_AUTOINC
0x80
#define ECON2_PKTDEC
0x40
#define ECON2_PWRSV
0x20
#define ECON2_VRPS
0x08
// ENC28J60 ECON1 Register Bit Definitions
#define ECON1_TXRST
0x80
#define ECON1_RXRST
0x40
#define ECON1_DMAST
0x20

#define ECON1_CSUMEN
0x10
#define ECON1_TXRTS
0x08
#define ECON1_RXEN
0x04
#define ECON1_BSEL1
0x02
#define ECON1_BSEL0
0x01
// ENC28J60 MACON1 Register Bit Definitions
#define MACON1_LOOPBK
0x10
#define MACON1_TXPAUS
0x08
#define MACON1_RXPAUS
0x04
#define MACON1_PASSALL
0x02
#define MACON1_MARXEN
0x01
// ENC28J60 MACON2 Register Bit Definitions
#define MACON2_MARST
0x80
#define MACON2_RNDRST
0x40
#define MACON2_MARXRST
0x08
#define MACON2_RFUNRST
0x04
#define MACON2_MATXRST
0x02
#define MACON2_TFUNRST
0x01
// ENC28J60 MACON3 Register Bit Definitions
#define MACON3_PADCFG2
0x80
#define MACON3_PADCFG1
0x40
#define MACON3_PADCFG0
0x20
#define MACON3_TXCRCEN
0x10
#define MACON3_PHDRLEN
0x08
#define MACON3_HFRMLEN
0x04
#define MACON3_FRMLNEN
0x02
#define MACON3_FULDPX
0x01
// ENC28J60 MICMD Register Bit Definitions
#define MICMD_MIISCAN
0x02
#define MICMD_MIIRD
0x01
// ENC28J60 MISTAT Register Bit Definitions
#define MISTAT_NVALID
0x04
#define MISTAT_SCAN
0x02
#define MISTAT_BUSY
0x01
// ENC28J60 PHY PHCON1 Register Bit Definitions
#define PHCON1_PRST
0x8000
#define PHCON1_PLOOPBK
0x4000
#define PHCON1_PPWRSV
0x0800
#define PHCON1_PDPXMD
0x0100
// ENC28J60 PHY PHSTAT1 Register Bit Definitions
#define PHSTAT1_PFDPX
0x1000
#define PHSTAT1_PHDPX
0x0800
#define PHSTAT1_LLSTAT
0x0004
#define PHSTAT1_JBSTAT
0x0002
// ENC28J60 PHY PHCON2 Register Bit Definitions
#define PHCON2_FRCLINK
0x4000
#define PHCON2_TXDIS
0x2000
#define PHCON2_JABBER
0x0400
#define PHCON2_HDLDIS
0x0100
// ENC28J60 Packet Control Byte Bit Definitions
#define PKTCTRL_PHUGEEN 0x08
#define PKTCTRL_PPADEN
0x04
#define PKTCTRL_PCRCEN
0x02
#define PKTCTRL_POVERRIDE 0x01
#endif //ENC28J60_H
//----------------------------------------------------------------------------

Khi giao tip vi ENC28J60 qua SPI, ngoi a ch th cn c Operating code iu khin thao tc
c/ghi/
Thm nh ngha cc code ny vo file trn (trn dng #endif //ENC28J60_H nh)
Code:

// SPI operation codes


#define ENC28J60_READ_CTRL_REG
#define ENC28J60_READ_BUF_MEM
#define ENC28J60_WRITE_CTRL_REG
#define ENC28J60_WRITE_BUF_MEM
#define ENC28J60_BIT_FIELD_SET
#define ENC28J60_BIT_FIELD_CLR
#define ENC28J60_SOFT_RESET

0x00
0x3A
0x40
0x7A
0x80
0xA0
0xFF

Khai bo a ch bt u v kt thc buffer d liu gi v nhn trn ENC28J60:


Code:
#define
#define
#define
#define

TXSTART_INIT
TXSTOP_INIT
RXSTART_INIT
RXSTOP_INIT

0x0000
0x05FF
0x0600
0x1FFF

//Dia
//Dia
//Dia
//Dia

chi
chi
chi
chi

bat
ket
bat
ket

dau buffer gui


thuc buffer gui
dau buffer nhan
thuc buffer nhan

//Khai bao kich thuoc frame ethernet max va min


#define MAX_FRAMELEN
1518
#define ETHERNET_MIN_PACKET_LENGTH
0x3C

Tip theo, m file enc28j60conf.h, thm vo cc khai bo v IO port s dng iu khin


ENC28J60 v mt s thng tin cu hnh khc (a ch MAC)
Code:
//---------------------------------------------------------------------------// Writen by NTTam - PTITHCM
//---------------------------------------------------------------------------#ifndef ENC28J60CONF_H
#define ENC28J60CONF_H
//
//Khai bao cac chan IO cho ENC28J60
#define ENC28J60_CONTROL_DDR
DDRB
#define ENC28J60_CONTROL_PORT
PORTB
#define ENC28J60_SPI_DDR
DDRB
#define ENC28J60_SPI_PORT
PORTB
//
#define ENC28J60_CONTROL_CS
3
#define ENC28J60_CONTROL_RESET
4
#define ENC28J60_SPI_SCK
7
#define ENC28J60_SPI_MISO
6
#define ENC28J60_SPI_MOSI
5
#define ENC28J60_SPI_SS
4
#define ENC28J60_SPI_CS
3
//
//Dinh nghia macro chon chip ENC28J60
#define ENC28J60_CS_LO()
ENC28J60_CONTROL_PORT &= ~(1<<ENC28J60_CONTROL_CS);
#define ENC28J60_CS_HI()
ENC28J60_CONTROL_PORT |= (1<<ENC28J60_CONTROL_CS);
//
#define ETH_INTERRUPT
INT2_vect
//
#if defined (__AVR_ATmega32__)
#define ETH_INT_ENABLE
GICR |= (1<<INT2)
#define ETH_INT_DISABLE GICR &= ~(1<<INT2)
#endif
#if defined (__AVR_ATmega644__) || defined (__AVR_ATmega644P__)
#define ETH_INT_ENABLE
EIMSK |= (1<<INT2)
#define ETH_INT_DISABLE EIMSK &= ~(1<<INT2)
#endif
// MAC address for this interface

#ifdef ETHADDR0
#define ENC28J60_MAC0
#define ENC28J60_MAC1
#define ENC28J60_MAC2
#define ENC28J60_MAC3
#define ENC28J60_MAC4
#define ENC28J60_MAC5
#else
#define ENC28J60_MAC0
#define ENC28J60_MAC1
#define ENC28J60_MAC2
#define ENC28J60_MAC3
#define ENC28J60_MAC4
#define ENC28J60_MAC5
#endif

ETHADDR0
ETHADDR1
ETHADDR2
ETHADDR3
ETHADDR4
ETHADDR5
'0'
'F'
'F'
'I'
'C'
'E'

#endif // ENC28J60CONF_H
//----------------------------------------------------------------------------

Trc ht ta cn 1 hm c v 1 hm ghi d liu vo 1 a ch xc nh trn ENC28J60 qua SPI:


M file enc28j60.c, thm vo cc hm (sau nh thm khai bo hm vo file header
enc28j60.h na nh)
Code:
//---------------------------------------------------------------------------// Writen by NTTam - PTITHCM
//---------------------------------------------------------------------------#include <avr/io.h>
#include "ntAVRnet.h"
#include "enc28j60.h"
#include "enc28j60conf.h"
#include <avr/pgmspace.h>
//---------------------------------------------------------------------------unsigned char enc28j60SPIRead(unsigned char op, unsigned char address)
{
unsigned char res;
ENC28J60_CS_LO();
SPDR = op | (address & ADDR_MASK);
while(!(SPSR & (1<<SPIF)));
SPDR = 0x00;
while(!(SPSR & (1<<SPIF)));
if(address & 0x80){
SPDR = 0x00;
while(!((SPSR) & (1<<SPIF)));
}
res = SPDR;
ENC28J60_CS_HI();
return res;
}
void enc28j60SPIWrite(unsigned char op, unsigned char address, unsigned char data)
{
ENC28J60_CS_LO();
SPDR = op | (address & ADDR_MASK);
while(!(SPSR & (1<<SPIF)));
SPDR = data;
while(!(SPSR & (1<<SPIF)));
ENC28J60_CS_HI();
}

ENC28J60 chia tp thanh ghi thnh cc bank, ta vit 1 hm set bank thanh ghi:
Trc ht ta khai bo 1 bin kiu char lu bank hin ti (thm vo u file):

Code:
unsigned char Enc28j60Bank;

V vit hm:
Code:
void enc28j60SetBank(unsigned char address)
{
if((address & BANK_MASK) != Enc28j60Bank)
{
enc28j60SPIWrite(ENC28J60_BIT_FIELD_CLR, ECON1, (ECON1_BSEL1|
ECON1_BSEL0));
enc28j60SPIWrite(ENC28J60_BIT_FIELD_SET, ECON1, (address &
BANK_MASK)>>5);
Enc28j60Bank = (address & BANK_MASK);
}
}

phc v cho vic c v ghi buffer d liu, ta vit tip 2 hm c v ghi buffer:
Code:
void enc28j60ReadBuffer(unsigned int len, unsigned char* data)
{
ENC28J60_CS_LO();
SPDR = ENC28J60_READ_BUF_MEM;
while(!(SPSR & (1<<SPIF)));
while(len--)
{
SPDR = 0x00;
while(!(SPSR & (1<<SPIF)));
*data++ = SPDR;
}
ENC28J60_CS_HI();
}
void enc28j60WriteBuffer(unsigned int len, unsigned char* data)
{
ENC28J60_CS_LO();
SPDR = ENC28J60_WRITE_BUF_MEM;
while(!(SPSR & (1<<SPIF)));
while(len--)
{
SPDR = *data++;
while(!(SPSR & (1<<SPIF)));
}
ENC28J60_CS_HI();
}

Da vo c s cc hm ny, ta xy dng cc hm c ghi thanh ghi iu khin, thanh ghi PHY


ca ENC28J60:
Code:
unsigned char enc28j60Read(unsigned char address)
{
enc28j60SetBank(address);
return enc28j60SPIRead(ENC28J60_READ_CTRL_REG, address);
}
void enc28j60Write(unsigned char address, unsigned char data)
{
enc28j60SetBank(address);
enc28j60SPIWrite(ENC28J60_WRITE_CTRL_REG, address, data);
}

unsigned int enc28j60PhyRead(unsigned char address)


{
unsigned int data;
enc28j60Write(MIREGADR, address);
enc28j60Write(MICMD, MICMD_MIIRD);
while(enc28j60Read(MISTAT) & MISTAT_BUSY);
enc28j60Write(MICMD, 0x00);
data = enc28j60Read(MIRDL);
data |= enc28j60Read(MIRDH);
return data;
}
void enc28j60PhyWrite(unsigned char address, unsigned int data)
{
enc28j60Write(MIREGADR, address);
enc28j60Write(MIWRL, data);
enc28j60Write(MIWRH, data>>8);
while(enc28j60Read(MISTAT) & MISTAT_BUSY);
}

Cc hm trn cho php truy xut y vo tp thanh ghi ca ENC28J60


Tip theo ta vit tip 2 hm gi v nhn 1 gi tin:
Code:
void enc28j60PacketSend(unsigned int len, unsigned char* packet)
{
enc28j60Write(EWRPTL, TXSTART_INIT);
enc28j60Write(EWRPTH, TXSTART_INIT>>8);
enc28j60Write(ETXNDL, (TXSTART_INIT+len));
enc28j60Write(ETXNDH, (TXSTART_INIT+len)>>8);
enc28j60SPIWrite(ENC28J60_WRITE_BUF_MEM, 0, 0x00);
enc28j60WriteBuffer(len, packet);
enc28j60SPIWrite(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_TXRTS);
}
unsigned int NextPacketPtr;
unsigned int enc28j60PacketReceive(unsigned int maxlen, unsigned char* packet)
{
unsigned int rxstat;
unsigned int len;
if( !enc28j60Read(EPKTCNT) )
return 0;
enc28j60Write(ERDPTL, (NextPacketPtr));
enc28j60Write(ERDPTH, (NextPacketPtr)>>8);
NextPacketPtr = enc28j60SPIRead(ENC28J60_READ_BUF_MEM, 0);
NextPacketPtr |= ((unsigned int)enc28j60SPIRead(ENC28J60_READ_BUF_MEM, 0))<<8;
len = enc28j60SPIRead(ENC28J60_READ_BUF_MEM, 0);
len |= ((unsigned int)enc28j60SPIRead(ENC28J60_READ_BUF_MEM, 0))<<8;
rxstat = enc28j60SPIRead(ENC28J60_READ_BUF_MEM, 0);
rxstat |= ((unsigned int)enc28j60SPIRead(ENC28J60_READ_BUF_MEM, 0))<<8;
len = ((len<maxlen)?(len) : (maxlen));
enc28j60ReadBuffer(len, packet);
enc28j60Write(ERXRDPTL, (NextPacketPtr));
enc28j60Write(ERXRDPTH, (NextPacketPtr)>>8);
enc28j60SPIWrite(ENC28J60_BIT_FIELD_SET, ECON2, ECON2_PKTDEC);
return len;
}

V hm khi ng IC ENC28J60:
c th nhanh chng truy xut thng tin cu hnh khi ng cho ENC28J60, ta lu ton b
thng tin ny vo mt array trong b nh flash cha a ch cc thanh ghi v gi tr khi to
tng ng, khai bo array ny trong file enc28j60.c:
Code:
prog_char enc28j60_config[44] PROGMEM = {
ETXSTL, LO8(TXSTART_INIT), //start lo
ETXSTH, HI8(TXSTART_INIT), //start hi
ETXNDL, LO8(TXSTOP_INIT ), //end lo
ETXNDH, HI8(TXSTOP_INIT ), //end hi
ERXSTL,
ERXSTH,
ERXNDL,
ERXNDH,

LO8(RXSTART_INIT), //start lo
HI8(RXSTART_INIT), //start hi
LO8(RXSTOP_INIT ), //end lo
HI8(RXSTOP_INIT ), //end hi

MACON2, 0x00,
MACON1, (MACON1_MARXEN | MACON1_RXPAUS | MACON1_TXPAUS),
MACON3, ( MACON3_PADCFG0 | MACON3_TXCRCEN | MACON3_FRMLNEN),
MAMXFLL, LO8(1518),
MAMXFLH, HI8(1518),
MABBIPG, 0x12, //half duplex
MAIPGL, 0x12,
MAIPGH, 0x0C, //half duplex
MAADR5,
MAADR4,
MAADR3,
MAADR2,
MAADR1,
MAADR0,
};

ENC28J60_MAC0,
ENC28J60_MAC1,
ENC28J60_MAC2,
ENC28J60_MAC3,
ENC28J60_MAC4,
ENC28J60_MAC5

Trong hm ny, ta s cn hm delay_us delay


Code:
void delay_us(unsigned short time_us)
{
unsigned short delay_loops;
register unsigned short i;
delay_loops = (time_us+3)/5*CYCLES_PER_US; // +3 for rounding up (dirty)
// one loop takes 5 cpu cycles
for (i=0; i < delay_loops; i++) {};
}

Trong hm delay trn ta cn 1 thng tin l s chu k my ca CPU/micro giy, do ta cn


thm cc thng tin ny vo file cu hnh chung:
M file ntAVRnet.h, thm vo cc define sau:
Code:
//---------------------------------------------------------------------------// Writen by NTTam - PTITHCM
//---------------------------------------------------------------------------#ifndef NTAVRNET_H
#define NTAVRNET_H
#ifndef F_CPU
#define F_CPU
12000000
// Cho toc do la 12MHz
#endif //F_CPU
#define CYCLES_PER_US ((F_CPU+500000)/1000000)
//So chu ky lenh trong 1 micro giay

#define LO8(x) ((x)&0xFF)


#define HI8(x) (((x)>>8)&0xFF)
#endif //NTAVRNET_H

V y l hm khi ng ENC28J60:
Code:
void enc28j60Init(void)
{
unsigned char i;
unsigned int timeout=0;
Enc28j60Bank = 0xFF;
ENC28J60_CONTROL_DDR |= (1<<ENC28J60_CONTROL_CS);
ENC28J60_CS_HI();
ENC28J60_SPI_PORT |= (1<<ENC28J60_SPI_SCK); //sck = hi
ENC28J60_SPI_DDR |= (1<<ENC28J60_SPI_SS)|(1<<ENC28J60_SPI_MOSI)|
(1<<ENC28J60_SPI_SCK); //SS,MOSI,SCK = OUT
ENC28J60_SPI_DDR &= ~(1<<ENC28J60_SPI_MISO); //MISO = IN
SPCR = (0<<SPIE)|(1<<SPE)|(0<<DORD)|(1<<MSTR)|(0<<CPOL)|(0<<CPHA)|(0<<SPR1)|
(0<<SPR0);
SPSR = (1<<SPI2X);
delay_us(65000);delay_us(65000);delay_us(65000);
enc28j60SPIWrite(ENC28J60_SOFT_RESET,0, ENC28J60_SOFT_RESET);
delay_us(65000);delay_us(65000);delay_us(65000);
while((!(enc28j60Read(ESTAT) & 0x01)) && (timeout<65000)){timeout++;};
if(timeout>=65000){timeout=0;}
NextPacketPtr = RXSTART_INIT;
for(i=0; i<2*22; i+=2){

enc28j60Write(pgm_read_byte(&enc28j60_config[i+0]),pgm_read_byte(&enc28j60_config[i+1]));
}
enc28j60PhyWrite(PHCON2, PHCON2_HDLDIS); //=no loopback of transmitted frames
enc28j60SPIWrite(ENC28J60_BIT_FIELD_SET, EIE, EIE_INTIE|EIE_PKTIE);
enc28j60SPIWrite(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_RXEN);
enc28j60PhyWrite(PHLCON, 0x347A);
}

Cui cng, nh thm phn khai bo tt c cc hm vit trn vo file header (enc28j60.h)
iu ny s gip truy xut d dng cc hm ny t cc module khc.
Bi tip theo s l lp trnh giao thc ethernet.
Thanks dinh_dong
Bi 4: Lp trnh giao thc Ethernet
(26/1/15)
HOT NG CA TCP/IP
- D liu truyn t ng dng, n mt trong 2 giao thc vn chuyn (TCP hay UDP). Mt gi tin
hay n v d liu (PDU) ca TCP/UDP thng c gi l segment (on d liu).
- on d liu xung lp Internet, giao thc IP cung cp thng tin nh a ch lun l (a
ch IP) v ng gi d liu vo 1 datagram, thng c gi l gi tin IP (IP packet).
- Datagram IP n lp truy cp mng ( y l giao thc ethernet), v c ng gi vo 1
hay nhiu khung d liu (frame ethernet), sau a xung tng vt l (v d IC ENC28J60)
gi i. Khung d liu c chuyn thnh mt lung cc bit truyn i trn mi trng
mng.
pha thu, qu trnh xy ra ngc li, tng vt l s nhn lung bit, khi phc li frame d
liu, giao thc ethernet pha nhn s x l frame d liu ny, tch ra gi tin IP (IP packet) v
y ln giao thc IP nu y l gi IP. Cn trong trng hp bn trong frame ethernet khng
phi l 1 gi IP m l 1 gi tin ca giao thc ARP th n s y gi ny sang cho giao thc ARP
x l (xem li hnh minh ha lu d liu gia cc giao thc).

Ti tng giao thc IP, gi IP s c x l, xc nh xem d liu cha bn trong l ca giao


thc no (TCP, UDP, hay ICPM) v chuyn n giao thc tng ng x l tip theo.
Cui cng, giao thc k (TCP, UDP, hay ICMP s x l tip segment d liu nhn c, xc nh
xem d liu ny l ca ng dng no (v d nh HTTP hay DHCP,) v chuyn d liu n ng
dng tng ng
Trc ht, ta cn nm r cu trc ca tt c cc gi tin ca mi giao thc c th x l c
thng tin cha trong n.
Ta to 1 file header mi l packet.h, file ny s dng cha m t cu trc ca tt c cc
gi tin ca cc giao thc s dng trong project ny:
Code:
//---------------------------------------------------------------------------// Writen by NTTam - PTITHCM
//---------------------------------------------------------------------------#ifndef PACKET_H
#define PACKET_H
#endif //PACKET_H

Trc ht ta tm hiu cu trc 1 frame ethernet:

Nh vy 1 frame ethernet bt u bng cc byte Preamble dng b v 1 byte Start of Frame


xc nh u frame (phn ny s c ENC28J60 t ng lc b, ta khng cn quan tm).
Tip theo l a ch MAC ca host nhn (destination address), a ch MAC ca host gi (source
address), mi a ch MAC ny gm 6 byte. K n l 2 byte length (cho bit chiu di) hoc
type (cho bit d liu cha trong frame l loi d liu ca giao thc lp trn no). K n l d
liu. Cui cng l phn kim tra li (FCS), phn ny cng c ENC28J60 x l, ta khng quan
tm.
Nh vy ta cn khai bo cu trc ca header frame ethernet (t phn a ch n 2 byte type)
trong file packet.h
Trc ht ta nh ngha 1 struc cho a ch MAC:
Code:
//-------------------------------------------------------------------------------------//Dia chi vat ly hay dia chi MAC (lop Ethernet)
struct ntEthAddr
{

unsigned char addr[6];


};

K n l header ca frame ethernet:


Code:
//-------------------------------------------------------------------------------------//Ethernet header
// Gom 14 byte:
// 06 byte dia chi dich
// 06 byte dia chi nguon
// 02 byte type (cho biet frame ethernet mang ben trong loai du lieu gi)
#define ETH_HEADER_LEN
14
struct ntEthHeader
{
struct ntEthAddr desAddr;
struct ntEthAddr srcAddr;
unsigned int type;
};

Ta cng nh ngha cc gi tr hng qui nh cho trng Type (tham kho ti liu v ethernet
bit thm cc gi tr ca trng ny):
Code:
//
#define ETH_TYPE_ARP 0x0806
#define ETH_TYPE_IP 0x0800
#define ETH_TYPE_IP6 0x86dd

Nhn tin y cng nh ngha lun cu trc ca cc frame ethernet cho VLAN (802.1q) v
VLAN Q-inQ (802.1ad), cu trc ca header MPLS. y l cc giao thc s dng ph bin trn
mng MEN (hay MAN-E) ca VNPT. Bn no khng quan tm n cc giao thc ny c th b
qua, ta ch tp trung vo giao thc ethernet thun ty.
Code:
//-------------------------------------------------------------------------------------//Ethernet header 802.1q VLAN Tagging
struct ntEth802_1qHeader
{
struct ntEthAddr desAddr;
struct ntEthAddr srcAddr;
unsigned int type;
unsigned int TPID;
unsigned int PCP_CFI_VID;
};
#define ETH_802_1Q_HEADER_LEN
18
//
#define ETH_802_1Q_TPID
0x8100
#define ETH_802_1Q_PCP_MASK
0xE000
#define ETH_802_1Q_CFI_MASK
0x1000
#define ETH_802_1Q_VID_MASK
0x0FFF
//-------------------------------------------------------------------------------------//Ethernet header 802.1ad Q-in-Q VLAN Tagging
struct ntEth802_1adHeader
{
struct ntEthAddr desAddr;
struct ntEthAddr srcAddr;
unsigned int type;
unsigned int OuterTPID;
unsigned int OuterPCP_CFI_VID;
unsigned int InnerTPID;

unsigned int InnerPCP_CFI_VID;


};
#define ETH_802_1AD_HEADER_LEN
22
//
#define ETH_802_1AD_TPID
0x88a8
#define ETH_802_QINQ_TPID1
0x9100
#define ETH_802_QINQ_TPID2
0x9200
#define ETH_802_QINQ_TPID3
0x9300
//-------------------------------------------------------------------------------------//Cau truc MPLS Header
struct ntMPLSHeader
{
unsigned int
HighLabelValue;
unsigned char
TrafficClass_Stack;
unsigned char
TTL;
};
#define MPLS_HEADER_LEN
4
//
#define MPLS_LOW_LABEL_MASK
0xF0
#define MPLS_TRF_CLS_MASK
0x0E
#define MPLS_STACK_MASK
0x01
//

Vy l xong phn khai bo cu trc frame ethernet. Tip theo l vit cc hm x l giao thc
ethernet.
Trong chng giao thc TCP/IP, giao thc ethernet ng vai tr lp truy nhp v truyn dn. Vic
gi v nhn d liu lp ethernet c thc hin da vo a ch vt l hay cn gi l a ch
MAC.
Trong mi frame ethernet u cha 2 a ch MAC: mt a ch ca host gi v 1 a ch ca
host nhn
khi lp ethernet nhn c 1 frame d liu, trc ht n s kim tra a ch host nhn xem c
phi l a ch ca n khng (tc l gi cho n), nu ng n s nhn frame ny v chuyn n
lp IP. Ngoi ra cn c 1 trng hp na lp ehternet s nhn frame: l nu a ch host
nhn l a ch broadcast (tc l gi cho tt c mi my trong mng LAN), trong trng hp
ny frame s c nhn v x l.
Ngoi vic kim tra a ch, trong frame ethernet cn c 1 trng cha m kim tra li gip
pht hin nhng li xy ra trong qu trnh truyn, cc frame b xc nh l c li s b b qua.
Trong mch ca chng ta, vic kim tra li v kim tra a c thc hin t ng bi IC
ENC28J60, do ta khng cn lp trnh cho cc chc nng ny. Mi khi nhn c 1 frame trn
ng truyn, ENC28J60 s kim tra li xem c sai st khng, tip n s i chiu a ch
host nhn vi a ch c cu hnh cho n (trong cc thanh ghi a ch MAC: MAADR0-5).
Nu khng c li v a ch l gi cho n, n s to 1 ngt cng (trn chn INT ca ENC28J60)
bo cho VK bit l n va nhn c 1 frame hp l v yu cu VK x l frame ny.
Vy cng vic ca chng ta l vit hm x l cho trng hp ny, cng nh cung cp 1 hm gi
i 1 frame d liu ( s dng khi mun gi d liu i). Bn cnh ta cng cn mt s hm
cung cp cc chc nng b sung nh set/get a ch MAC,
To 1 file source "ethernet.c" vit module ethernet v file header cho n "ethernet.h"
File ethernet.c
Code:
//---------------------------------------------------------------------------// Writen by NTTam - PTITHCM
//---------------------------------------------------------------------------#include <avr/io.h>
#include <avr/pgmspace.h>
#include "packet.h"
#include "enc28j60.h"
#include "enc28j60conf.h"
#include "ethernet.h"

File ethernet.h
Code:
//---------------------------------------------------------------------------// Writen by NTTam - PTITHCM
//---------------------------------------------------------------------------#ifndef ETHERNET_H
#define ETHERNET_H
#endif //ETHERNET_H

Bun ng qu, mai vit tip....

Lp trnh cho giao thc ethernet (tip theo)


Trc ht, ta khai bo 1 buffer trn b nh RAM ca VK lu tr frame d liu m ta cn x
l.
Kch thc ca buffer ny s bng kch thc ln nht ca 1 segment d liu m h thng ca
ta c th x l (MTU) + kch thc header TCP + kch thc header UDP + kch thc header
ca frame.
Trong :
- Vi giao thc TCP/IP th MTU max l 1460
- Kch thc Header ca TCP l 20 bytes
- Kch thc Header ca IP l 20 bytes ( y xem nh khng c trng Option trong Header
IP, cu trc gi IP s c gii thch chi tit phn lp trnh cho giao thc IP).
- Kch thc Header ca frame Ethernet l 14 byte.
Vy trc ht ta thm cc khai bo kch thc ny vo file ethernet.h
Code:
#ifndef

MTU_SIZE
#define

MTU_SIZE 1460

#endif
#ifndef

IP_HEADER_LEN
#define IP_HEADER_LEN
20
#endif //IP_HEADER_LEN
#ifndef
TCP_HEADER_LEN
#define TCP_HEADER_LEN
20
#endif //TCP_HEADER_LEN
//
#ifndef ETHERNET_BUFFER_SIZE
#define ETHERNET_BUFFER_SIZE
(700+ETH_HEADER_LEN+IP_HEADER_LEN+TCP_HEADER_LEN)
#endif

S d ta thm iu kin (#ifndef #endif) l v thc ra kch thc Header TCP v IP s c


nh ngha trong file packet.h, MTU_SIZE s c nh ngha trong phn config thng tin chung
ca chng trnh, do hin nay ta cha vit cc phn nn tm thi nh ngha trc.
Sau khai bo buffer dnh cho frame ethernet trong file source (ethernet.c):
Code:
unsigned char ethBuffer[ETHERNET_BUFFER_SIZE];

Tip theo ta vit mt s hm cung cp cc chc nng c bn cho lp ethernet:


Code:
//---------------------------------------------------------------------------//Ham khoi tao chip Ethernet
void ethInit(void)
{

enc28j60Init();
ETH_INT_ENABLE;
}
//-------------------------------------------------------------------------------------//Ham goi 1 frame xuong chip ethernet
void ethSendFrame(unsigned int len, unsigned char* packet)
{
enc28j60PacketSend(len, packet);
}
//-------------------------------------------------------------------------------------//Ham doc 1 frame ethernet tu chip ethernet ve buffer tren RAM cua CPU
unsigned int ethGetFrame(unsigned int maxlen, unsigned char* packet)
{
return enc28j60PacketReceive(maxlen, packet);
}
//-------------------------------------------------------------------------------------//Ham doc dia chi MAC hien tai tu chip ethernet, luu vao buffer macaddr[6]
void ethGetMacAddress(unsigned char* macaddr)
{
*macaddr++ = enc28j60Read(MAADR5);
*macaddr++ = enc28j60Read(MAADR4);
*macaddr++ = enc28j60Read(MAADR3);
*macaddr++ = enc28j60Read(MAADR2);
*macaddr++ = enc28j60Read(MAADR1);
*macaddr++ = enc28j60Read(MAADR0);
}
//-------------------------------------------------------------------------------------//Ham set dia chi MAC (dang luu trong buffer macaddr[6] xuong chip ethernet
void ethSetMacAddress(unsigned char* macaddr)
{
enc28j60Write(MAADR5, *macaddr++);
enc28j60Write(MAADR4, *macaddr++);
enc28j60Write(MAADR3, *macaddr++);
enc28j60Write(MAADR2, *macaddr++);
enc28j60Write(MAADR1, *macaddr++);
enc28j60Write(MAADR0, *macaddr++);
}
//-------------------------------------------------------------------------------------//Ham tra lai con tro den buffer ethernet (tren RAM cua CPU)
unsigned char* ethGetBuffer(void)
{
return ethBuffer;
}

Nhc li l truy xut c n cc hm trong module enc28j60.c, n y cc bn nht


thit phi thm cc khai bo hm vit trong enc28j60.c vo file header enc28j60.h. Tc
l trong file enc28j60.h phi c cc dng khai bo ny:
Code:
//---------------------------------------------------------------------------unsigned char enc28j60SPIRead(unsigned char op, unsigned char address);
void enc28j60SPIWrite(unsigned char op, unsigned char address, unsigned char data);
void enc28j60SetBank(unsigned char address);
void enc28j60ReadBuffer(unsigned int len, unsigned char* data);
void enc28j60WriteBuffer(unsigned int len, unsigned char* data);
unsigned char enc28j60Read(unsigned char address);
void enc28j60Write(unsigned char address, unsigned char data);
unsigned int enc28j60PhyRead(unsigned char address);
void enc28j60PhyWrite(unsigned char address, unsigned int data);
void enc28j60PacketSend(unsigned int len, unsigned char* packet);
unsigned int enc28j60PacketReceive(unsigned int maxlen, unsigned char* packet);
void delay_us(unsigned short time_us);
void enc28j60Init(void);

Tip theo ta vit phn x l khi ENC28J60 nhn c 1 frame d liu hp l.


Nh ni trc , khi ENC28J60 nhn c 1 frame d liu hp l, n s to 1 ngt bo
cho VK bit v x l d liu nhn c ny. Nh vy ta cn vit mt ISR ngt tng ng cho
s kin :
Code:
//-------------------------------------------------------------------------------------//Vector ngat cua ethernet, mot ngat ngoai se duoc khoi tao boi chip ethernet
// moi khi no nhan duoc 1 frame ethernet (dung dia chi cua no)
ISR (ETH_INTERRUPT)
{
eth_got_frame = 1;
time_watchdog = 0;
ETH_INT_DISABLE;
}

Trong hm ny ta c s dng nh ngha vector ngt (ISR), do ta cn include file tng ng


vo. Thm dng ny vo u file "ehternet.c"
Code:
#include <avr/interrupt.h>

Trong hm ny, ta s dng 2 bin ton cc l eth_got_frame v time_watchdog, hai bin ny


cn c khai bo trong file enc28j60.c (nn du file)
Code:
unsigned char eth_got_frame = 0;
volatile unsigned int time_watchdog;

Gii thch: thay v vit ton b phn x l trong hm ngt (ISR), trong hm ngt ta ch n
gin l set bin eth_got_frame = 1 bo cho bit c 1 frame ang ch x l, bin ny
(eth_got_frame) s lin tc c kim tra bi hm dch v ethernet (ethService) m ta s vit
sau y, hm ny (ethService) s lin tc c gi trong 1 vng lp chng trnh chnh (hm
main trong file ntAVRnet.c) thc thi lin tc.
Cch vit ny nhm trnh xy ra hin tng ngt chng ngt, c th dn n chng trnh thc
thi khng ng mong mun do ni dung hm ngt qu di, cha thc thi xong xy ra 1 ngt
khc.
Cn bin time_watchdog l mt bin nhm pht hin cc li dn n treo cc giao thc mng
hoc IC ENC28J60. Bin ny s c tng lin tc bi timer nhng li c reset v 0 mi khi
nhn c 1 frame ethernet mi, iu ny cho php pht hin 1 khong thi gian qu lu m
ta khng nhn c frame ethernet no (khi bin time_watchdog tng n mt gi tr ngng),
khi ta gi thit l ENC28J60 b treo hay pht sinh li, lc ta s gi hm reset IC ny v
khi ng li giao thc ethernet. iu ny trong thc t rt hu ch, n gip mch ca chng ta
chy n nh hn rt nhiu.
ng thi ta cng disable ngt ngoi ny trong thi gian ch x l frame.
Vy ta vit tip phn x l frame ethernet trong hm ethService nh sau:
Code:
//-------------------------------------------------------------------------------------//Ham duoc goi lien tuc de thuc thi cac tac vu cua giao thuc ethernet
void ethService(void)
{
int len;
struct ntEthHeader* ethPacket;
if(!eth_got_frame) return;
eth_got_frame = 0;
// look for a packet
len = ethGetFrame(ETHERNET_BUFFER_SIZE, ethBuffer);

if(len)
{
ethPacket = (struct ntEthHeader*)&ethBuffer[0];
#ifdef ETH_DEBUG
printf("Received packet len: %d, type:", len);
#endif
if(ethPacket->type == HTONS(ETH_TYPE_IP))
//Neu day la frame danh cho giao thuc IP
{
#ifdef ETH_DEBUG
printf("IP packet\r\n");
#endif
arpIPPacketIn((unsigned char*)&ethBuffer[0]);
IPProcess( len-ETH_HEADER_LEN, (struct
ntIPHeader*)&ethBuffer[ETH_HEADER_LEN] );
}
else if(ethPacket->type == HTONS(ETH_TYPE_ARP))
//Neu day la 1 frame cua giao thuc ARP
{
#ifdef ETH_DEBUG
printf("ARP packet\r\n");
#endif
arpArpProcess(len, ethBuffer );
}else{
#ifdef ETH_DEBUG
printf("Unknown packet:%x\r\n",ethPacket->type);
#endif
ethInit();
}
ETH_INT_ENABLE;
}
return;
}
//--------------------------------------------------------------------------------------

Gii thch:
Hm ny khi pht hin c frame mi (bin eth_got_frame khc 0) th tin hnh kim tra trng
Type trong header frame ethernet xem d liu cha trong frame l ca giao thc no (IP
hay ARP) v s gi hm tng ng ca giao thc x l.
C mt lu quan trng l trong trnh bin dch gcc (cng nh cc trnh bin dch ngn ng C
khc cho AVR), i vi cc bin c kch thc ln hn 1 byte (int, double, long,) th th t cc
byte trong b nh ca AVR c sp xp theo th t ngc li vi th t trong cc header ca
gi tin (frame ethernet, IP packet,). Do khi c cc bin ny ra t buffer ethernet cng
nh trc khi ghi vo buffer, ta phi i th t cc byte ny. Ta vit mt s macro cho mc ch
ny v lu lun trong file packet.h s dng sau ny.
Code:
//-------------------------------------------------------------------------------------#define HTONS(s)
((s<<8) | (s>>8))
//danh cho bien 2 byte
#define HTONL(l)
((l<<24) | ((l&0x00FF0000l)>>8) | ((l&0x0000FF00l)<<8) |
(l>>24)) //danh cho bien 4 byte
//

Lu l trong hm ny ta c gi cc hm ca giao thc lp trn (IP v ARP). l cc hm


arpIPPacketIn, IPProcess, v arpArpProcess. Cc hm ny ta vn cha vit nn khi bin dch
file ethernet.c s c bo li thiu cc hm ny.
cho mc ch debug sau ny, trong hm ta c s dng hm xut ra cng serial l printf.
Hm ny cc bn t vit ly dng uart nh. Trong ni dung hng dn ny tp trung vo giao

thc TCP/IP thi.


Sau khi x l xong frame, ta cn enable ngt ngoi tr li.
n y l c bn xong giao thc ethernet, tip theo s l giao thc IP v ARP, rc ri hn
nhiu.
Bi 5: Lp trnh cho giao thc IP (Internet Protocol) v giao thc ARP (Address
Rolution Protocol)
Trc ht, ta cn tm hiu v hot ng ca giao thc IP.
(phn ny vit mt cch n gin v d hiu nht cho dn in t, khng chuyn v network
c th hiu phn no hot ng ca cc giao thc c th hiu code v t vit code, dn IT
vo c ng ci nh)
Cch thc m d liu c gi qua giao thc IP c tin hnh nh sau:
- Khi nhn c 1 segment d liu (t giao thc lp trn l TCP hay UDP) cn gi n ch no
, a ch ch ny phi c xc nh bng a ch IP (tc l a ch mng hay a ch lun l).
Lp giao thc IP s gn thm vo u segment d liu mt header IP to thnh gi IP hon
chnh. Trong header IP ny c cha 2 thng tin quan trng, l a ch host gi (source IP
address) v a ch host nhn (destination IP address). a ch source ng nhin l a ch
ca bn thn n, cn a ch ch phi c cung cp cho lp IP khi mun gi d liu qua giao
thc ny.
- Gi tin IP ny sau c chuyn n lp giao thc ethernet thm phn header ethernet
vo v gi i.
- Nhng nh phn trc ta bit, giao thc ethernet li gi cc frame d liu i da vo 1
loi a ch khc l a ch MAC (hay cn gi l a ch vt l). Ti sao li cn n 2 a ch nh
vy? L do l a ch vt l ch c gi tr trong phm vi mng LAN, n s khng th gip xc
nh v tr host bn ngoi phm vi mng LAN. Khi gi d liu ra ngoi mng LAN, cc router
s chuyn d liu i da v a ch IP.
- Nh vy trong phn a ch MAC ngun v a ch MAC ch trong header ca frame ehternet,
ta s in cc a ch no? i vi a ch MAC ngun, ng nhin ta s in a ch MAC ca
chnh ENC28J60 c xc lp. Nhng cn a ch MAC ch, s c 2 trng hp xy ra:
+ Nu host ch nm trong cng 1 mng LAN vi chng ta, ta s in a ch MAC ch l a
ch tng ng ca host ch. Frame d liu s c gi thng n ch.
+ Nu host ch nm bn ngoi mng LAN, r rng ta khng th gi d liu trc tip n host
ch m phi thng qua gateway, khi a ch MAC ch phi l a ch gateway. ( d hiu,
c hnh dung ta gn mch ny ti nh, sau modem ADSL cng vi 1 my tnh bn ti nh,
nu mch ca chng ta cn gi d liu n my tnh cng ti nh, trong cng mng LAN, n
s gi trc tip theo a ch MAC ca my tnh . Nhng nu cn gi d liu n 1 my tnh
bn ngoi, nm trn mng Internet, khi n khng th gi frame d liu thng n my tnh
kia m n phi gi qua gateway, trong trng hp ny chnh l modem ADSL. Nh vy lc
a ch MAC ch phi l a ch MAC ca gateway).
- Vn cn mt vn na m ta phi gii quyt. l trong c hai trng hp trn, d l cn
gi cho gateway hay thng n host ch, th n y, ta mi ch bit a ch IP ca host ch
(hay ca gateway) m khng bit a ch MAC tng ng. Vy ny sinh mt vn l lm sao
bit c a ch MAC ca mt host khi bit a ch IP?

n y, chnh l pht sinh vai tr ca giao thc phn gii a ch (APR Address Resolution
Protocol). Vai tr ca giao thc ny l tm ra a ch MAC khi bit a ch IP ca 1 host.
Hot ng ca giao thc ARP:
- Cch thc lm vic ca giao thc ARP thc ra kh n gin. Nhim v ca n l khi giao thc
IP hi n: Host c a ch IP l a.b.c.d th a ch MAC l bao nhiu? th n phi tr li ngay:
a ch MAC ca n l XX:XX:XX:XX:XX:XX!. Chc nng ny trong project ca chng ta s
c cung cp bi hm arpIpOut (xem li lu d liu vo ra). Tc l trc khi giao thc IP
chuyn d liu xung cho giao thc ethernet, n s gi hm arpIpOut phn gii a ch
MAC cho host ch.
- Tuy nhin ch chng cha gii thch cho hot ng ca ARP. Cu hi tip theo s l: Vy
ARP ly thng tin u tr li cho cu hi trn?
- Cch thc n gii quyt vn cng n gin khng km: giao thc ARP duy tr mt bng gi
l ARP cache gm 2 ct, mt ct ghi a ch IP, mt ct ghi a ch MAC tng ng vi a ch IP
. Mi khi c hi bi giao thc IP, n s tra bng ny tm cu tr li.
- Vy n y, cc bn phi ny ra ngay 1 cu hi k tip: vy nhng g cha trong bng ARP
cache t u m c, khi mi khi ng h thng, bng ny ng nhin s trng trn. V
chuyn g s xy ra khi giao thc ARP c hi v 1 a ch IP, m khi n tra trong bng ARP th
khng thy?
- Cch gii quyt ca giao thc ARP nh sau: khi c hi v mt a ch IP a.b.c.d no m
khng c sn trong bng ARP cache, n s lp tc la ln trong mng LAN: Ai l ngi c a
ch IP l a.b.c.d? Cc my tnh trong mng LAN u nghe c cu hi ny, v l d nhin ch
c ng my tnh c a ch IP a.b.c.d s tr li: L ti y, ti c a ch MAC l
XX:XX:XX:XX:XX:XX!. Vy giao thc ARP s lp tc thm cp a ch IP a.b.c.d v a ch MAC
XX:XX:XX:XX:XX:XX vo trong bng ARP cache v tr li li cho giao thc IP: a ch MAC ca
n l XX:XX:XX:XX:XX:XX!.
- Nghe c v bun ci nhng trong thc t, trn my tnh ca chng ta, mi vic din ra ng
nh vy, vic la ln ca ARP c thc hin bng cch n gi i mt gi tin c tn gi l ARP
request di dng broadcast, tc l gi n mi my trong mng LAN, a ch MAC ch ca gi
broadcast s l FF:FF:FF:FF:FF:FF. Trong gi ARP request c cha a ch IP m n cn tm. Tt
c cc my tnh trong mng LAN s nhn c gi tin ny, v my tnh c a ch IP trn s tr
li bng bn tin ARP reply, trong bn tin ny s c a ch MAC ca n.
- l cch th nht giao thc ARP in thng tin vo bng ARP cache. Cn c 1 cch na
kh n gin gip n in y thng tin vo bng ARP cache: l mi khi c 1 gi tin IP n,
l d nhin l pha host gi gi tin ny in y thng tin a ch MAC (cha trong
header ehternet) v a ch IP ca n (cha trong header IP). Nh vy giao thc ARP s ly cp
a ch ny v cp nht vo bng ARP cache.
- iu cui cng cn lu v bng ARP cache ny l cc dng (tc cp a ch IP MAC) cha
trong n khng c duy tr mi mi m c 1 thi gian timeout, qu thi gian ny m khng c
thng tin cp nht cho cp a ch th n s b xa khi ARP cache, v nu l giao thc IP
cn gi d liu cho a ch IP b xa th ARP s i hi li v a ch IP .
Note: xem c bng arp cache trn my tnh ca mnh, cc bn c th m ca s
command (vo Start->Run->g cmd, nhn Enter), sau g lnh "arp -a".

By gi ta bt tay vo vit code:


Vic trc tin phi lm l khai bo cu trc header IP v cu trc gi ARP trong file packet.h.
Cu trc ca gi IP nh sau:

- ngha cc field trong header IP:


+ Version (c chiu di 4 bit): cho bit phin bn ca giao thc, i vi trng hp ca chng
ta, giao thc l IP version 4, trng ny s lun c gi tr l 4 (0100)
+ Header Length (4 bit): cho bit chiu di ca header IP, tnh theo n v 4 byte (32 bit)
+ TOS (8 bit): Type of Service
+ Total Length (16 bit): 16 bit tng chiu di ca gi IP gm c phn header
+ Identification (16 bit): dng nhn din cc phn on ca gi IP
+ Flags: gm 3 bit
. Bit u tin: khng s dng
. Bit 2: DF (Dont Fragment) = 1 c ngha l khng phn on gi ny
. Bit 3: MF (More Fragment) = 0 => y l phn on cui cng
+ Fragmented offset (13 bit): di (n v 8 byte) tnh t im bt u ca Header ti im
bt u ca phn on
(3 trng trn: Identification, Flags, Fragmented offset dng cho trng hp c bit khi ta cn
chia on d liu ban u thnh nhiu phn on, ng gi trong cc gi tin nh hn, khi ta
cn dng cc trng ny cho mc ch rp li cc phn on khi phc li on d liu ban
u, trong project ca chng ta s khng c x l trng hp ny).
+ TTL (Time to Live) (8 bit): thi gian tn ti trn mng hoc s chng trn mng m gi i
qua trc khi b hy b
+ Protocol (8 bit): nhn din Protocol trn lp IP
+ Header checksum (16 bit): sa sai cho phn Header
+ Cc vng a ch ngun, a ch ch: a ch IP 32 bit
+ Option: cc ty chn dng cho vic kim tra: Loose source routing, Strict source routing,
Record route v Timestamp
+ Padding: Gm cc s zero c thm vo sao cho chiu di ca vng Header l bi s ca 32
bit
(Trong phm vi project ca chng ta, s khng c phn option v padding)
Vy ta khai bo trong file packet.h ni dung nh sau:
Code:
//--------------------------------------------------------------------------------------

//Cau truc IP header


struct ntIPHeader
{
unsigned char
unsigned char
unsigned int
unsigned int
unsigned int
unsigned char
unsigned char
unsigned int
unsigned long
unsigned long
unsigned char
};
#define IP_HEADER_LEN
#define IP_PROTO_ICMP
#define IP_PROTO_TCP
#define IP_PROTO_UDP

verHdrLen;
ToS;
Len;
IDNumber;
Offset;
TTL;
Protocol;
Checksum;
srcIPAddr;
desIPAddr;
Option[4];
20
1
6
17

Cn y l cu trc gi ARP:

- ngha cc trng:
+ Hardware type (2 bytes): cho bit loi a ch phn cng, i vi a ch MAC ca giao thc
ethernet th gi tr ny c qui nh l "0x0001".
+ Protocol type (2 bytes): cho bit loi a ch giao thc lp trn, i vi a ch IP, gi tr ny
c qui nh l 0x0800.
+ HLEN (1 byte): cho bit chiu di ca a ch vt l (a ch MAC).
+ PLEN (1 byte): cho bit chiu di ca a ch giao thc (a ch IP)
+ Operation (2 bytes): cho bit hot ng ang thc hin trong gi tin ny (request hay reply).
+ Sender H/W (hardware address, 6 bytes): a ch vt l ca pha gi.
+ Sender IP (4 bytes): a ch IP ca pha gi.
+ Target H/W (6 bytes): a ch vt l ca pha nhn, nu cha bit th s l cha ton 0.
+ Target IP (4 bytes): a ch IP ca pha nhn.
Vy ta khai bo cu trc gi ARP trong file packet.h nh sau:
Code:
//-------------------------------------------------------------------------------------//Cau truc ARP header
struct ntARPHeader

{
unsigned int
unsigned int
unsigned char
unsigned char
unsigned int
struct ntEthAddr
unsigned long
struct ntEthAddr
unsigned long

hwType;
protocol;
hwLen;
protoLen;
opcode;
shwaddr;
sipaddr;
dhwaddr;
dipaddr;

};
#define ARP_OPCODE_REQUEST
#define ARP_OPCODE_REPLY 2
#define ARP_HWTYPE_ETH

1
1

Khng c thi gian vit chi tit hn. Bn no c thy ch no kh hiu th c hi nh.
Nguyn vn bi vip_co_don

Cho anh h !.
Em cng ang tm hiu web sever nhng nhng em ang lm trn PIC32 v s dng TCP/IP
Stack ca Microchip. Anh cho em hi mt cht ah:
Nu em mun lu mt trang web vo mt flash ROM sau khi ta bt trnh duyt web ln th
c th truy cp v iu khin board ny th c ch ca n l g mong anh ch gim ?.
Cm n anh tht nhiu !.
Cho em.
D l trn PIC hay AVR hay bt c micro controller no th c ch cng nh nhau thi (thm ch
trn my tnh th cng tng t), ch khc l i vi PIC th Microchip cung cp y b
th vin cho cc giao thc ethernet, ip, arp, udp, tcp, dhcp, http, khng cn phi vit li nh
anh ang lm cho AVR. C ch nh sau:
- Khi ta m my tnh ln, m trnh duyt v g vo a ch ca webserver (PIC hay AVR g cng
th), gi s y ta g vo a ch IP nh sau: http://192.168.1.10
- Sau khi nhn enter th my tnh ca chng ta s gi i mt bn tin request ca giao thc
HTTP (Hyper Text Transfer Protocol, giao thc truyn/nhn ni dung trang web), thng l
HTTP Get thng qua giao thc TCP (vi cng TCP c qui nh cho giao thc HTTP l 80) n
a ch webserver trn.
- Webserver, y chnh l vi iu khin ca chng ta (PIC hay AVR) nhn c bn tin ny
(tt nhin bn tin ny s i qua ht cc lp giao thc ethernet, IP, TCP ri mi n HTTP). Ti
y vi iu khin s c v phn tch bn tin HTTP request ny bit my tnh ang yu cu
ti ni dung trang web no.
- Sau vi iu khin s ly ni dung trang web ny (c son tho theo ngn ng HTML)
cha trn trn flash ROM, n cng c th thm vo trang web mt s thng tin (v d c
gi tr t cc sensor cm bin nhit v a vo trong trang web), v gi ton b ni dung
trang web thng qua giao thc TCP tr li cho my tnh. Nu ni dung trang web ln n c th
c gi i trn rt nhiu gi tin, v mi gi tin ch cha ti a 1460 byte d liu m thi.
- My tnh nhn ni dung trang web v trnh duyt s hin th ln cho chng ta thy.
- iu khin board t xa qua web, trn trang web ta c th thit k mt nt nhn chng
hn. Khi ta nhn nt ny trn trnh duyt, my tnh s gi i mt bn tin HTTP na l HTTP
Post, trong bn tin ny s cha cc thng tin v trng thi cc nt option hay cc gi tr trong
cc edit text c trn trang web.
- Vi iu khin s nhn bn tin HTTP post ny, phn tch d liu cha trong c p ng
tng ng (bt tt relay chng hn) sau n s gi tr li ln na ni dung trang web cp
nht nhng thay i va ri (v d bt reley th trn web s c 1 hnh trn i sang mu
chng hn). Trnh duyt s update ni dung ny ln v ta s thy c tc ng ca thao tc
iu khin .

T t anh s vit v gii thch tt c cc hot ng trn AVR, trn PIC cng th nhng cc
hm c Microchip cung cp sn m thi.

Nguyn vn bi dinh_dong

Thy cho em hi ch ny, v va c em va tng tng thc th cho d hiu.


Trong mi frame ethernet u cha 2 a ch MAC: mt a ch ca host gi v 1 a ch ca
host nhn
.
Cu hi:S host truyn nhn trong trng hp ny l bao nhiu : 2 hay >2 host ? V em ngh 2
host l TH ring, 1 host truyn 1 host nhn, th host nhn check IP l chnh n.
Nu host nhn c frame m n kim tra ko phi IP add(dst) ca n th n s x l nh th no,
c phi lc ny IP add(dst) l IP broadcast?
V sau ti mt host no , check IP add l ca chnh n th TH1 c xy ra, phi ko ?
Em lin tng TCP/IP lc ny x l IP nh mt Router check IP cho c 1 mng LAN, ...kt ni vi
n.
Nu frame c gi cho tt c my tnh trong LAN, th s ko c host ch c th no ?
Nu vi HTTP, hay 1 ng dng no khc th iu ny c th c, nhng vi cc ng Email
chng hn, cn tnh bo mt ring t th IPbroadcast li ko c- do cc my u nhn c
frame x l.
EM c vi cu, ko bit ng sai th no?
Cu hi ca em thc ra rt hay, vn ny ti khng gii thch chi tit trong phn giao thc
ethernet.
- Giao thc ethernet ch h tr 2 hnh thc truyn: unicast: tc l 1 host gi, 1 host nhn; v
broadcast, tc l 1 host gi, tt c cc host trong mng LAN u nhn.
- Trong mng LAN c bn, s dng 1 HUB kt ni cc my tnh vi nhau trong mng LAN.
Khi mt my tnh gi i mt frame ethernet, bt k l n gi unicast hay broadcast, th tt c
cc my tnh trong mng LAN (kt ni vi HUB) u nhn c frame . Nhng mi my
tnh s i chiu a ch MAC nhn vi a ch ca chnh n ( y ch kim tra a ch MAC,
khng kim tra a ch IP, khi ln giao thc IP th mi kim tra a ch IP), v cc host s ch
nhn frame v chuyn ln giao thc IP trong 2 trng hp:
+ Hoc a ch l ca chnh n
+ Hoc a ch l broadcast
- Vy iu g s xy ra nu mt my tnh no ph v lut chi, nhn d liu khng phi
dnh cho n, nh vy phi chng n c th nghe trm d liu gi cho my tnh khc.
- Cu tr li y l: ng nh vy, mng LAN kiu ny hon ton khng c bo mt, vi cc
phn mm nghe trm d liu, mt my tnh c th nghe trm d liu ca cc my khc trong
cng mng LAN.
- y thit b HUB dng kt ni cc my tnh to thnh mng LAN ch n gin l khi nhn
c d liu n 1 port ca n, n s khuych i v pht ra li tt c cc port, tt c
my tnh ni n n u nhn c d liu.
[Flash]http://www.shareswf.com/media/games/swf/16193.swf[/Flash]
[flash=300,200]http://www.shareswf.com/media/games/swf/16193.swf[/flash]
[FLASH=300,300]http://www.shareswf.com/media/games/swf/16193.swf[/FLASH]
- Tt nhin ngi ta cng nhn ra hn ch ca HUB, cng nh mt s hn ch khc, v pht
trin mt thit b "thng minh" hn HUB, l SWITCH.
- V hnh thc, SWITCH cng c nhiu port v dng kt ni cc my tnh to thnh mng
LAN ging HUB, tuy nhin s khc bit l: mi khi nhn c d liu n 1 port ca n,
SWITCH s kim tra a ch MAC ch trn frame, sau n tm xem my tnh c a ch MAC

tng ng ang nm port no ca n, v chuyn d liu n port . Nh vy ch c my


tnh nhn c d liu m thi.
[FLASH]http://www.swfcabin.com/open/1320370008[/FLASH]
Hin nay hu ht cc mng LAN l dng SWITCH, tr cc thit b c s port t (<=5 port) l cn
dng HUB.
Vic gi broadcast trn mng LAN ch dng cho mt s trng hp c bit, v d nh cho giao
thc ARP, hay khi giao thc IP yu cu gi broadcast (giao thc IP th c 3 hnh thc gi l
unicast, multicast v broadcast). a ch MAC broadcast c qui nh l FF:FF:FF:FF:FF:FF.
Mc nh, vic gi broadcast ra ngoi phm vi mng LAN l khng c php, cc router s
chn cc bn tin broadcast v khng cho n ra khi phm vi mng LAN.
Hy vng cu tr li trn gii p c thc mc ca em, nu cn cha r c hi tip nh.
Nguyn vn bi dinh_dong

Cu hi:ARP: Em ngh ti 1 ci l: mnh ko nh 192.xxx.x.x na m c th nh ch no


nh avrnet v Enter th c hin th c webserver khng ? V vai tr ca ARP trong trng
hp ny th no.
Li mt cu hi rt ng bn lun na, tuy nhin vn ny khng thuc giao thc ARP m
thuc mt h thng khc, ta gi l h thng tn min (domain name system).
ng ra, my tnh ch gi v nhn d liu trn mng da vo a ch IP. Tc l l ra truy cp
vo trang ch yahoo chng hn, ta phi g a ch IP server ca
yahoo: http://98.137.149.56 (cc bn c th th).
Tuy nhin r rng l cch ny qu kh nh vi ngi s dng, do ngi ta mi ngh ra mt
loi a ch gi nh d nh hn, l tn min (domain name) nh vy thay v
g: http://98.137.149.56 ta c th g: http://www.yahoo.com.
Nhng vn li pht sinh l my tnh th khng hiu tn min, i vi n th nht thit phi c
a ch IP th mi gi nhn d liu trn mng c.
V vy ngi ta duy tr trn mng Internet mt h thng server gi l Domain Name System
Server, vit tt l DNS server (nu chng ta vo phn cu hnh a ch IP tnh cho my tnh s
thy phn ny). Nhim v ca cc server ny l khi c 1 my tnh bt k hi n v mt tn
min, n s tr li ngay tn min ng vi a ch IP no.
Vy by gi, nu chng ta m trnh duyt v g vo http://www.yahoo.com th c ch s
nh sau:
- My tnh s gi i mt cu hi n DNS server l: tn min http://www.yahoo.com th tng
ng vi a ch IP no?
- DNS server s tr li: Tn min www.yahoo.com tng ng vi a ch IP 98.137.149.56.
- My tnh s truy cp theo a ch 98.137.149.56 v ti ni dung trang web yahoo v.
Vy c th s dng tn min, my tnh bt buc phi bit t nht mt a ch DNS server.
Thng tin v DNS server s c cung cp thng qua giao thc DHCP hoc cu hnh tnh.
C rt nhiu DNS server trn mng, mi nh cung cp dch v Internet ca Vit Nam chng
hn u c 1 vi DNS server. V d VNPT c cc DNS server: 203.162.4.190; 203.162.4.191;
203.162.4.1. Viettel c 203.113.131.1; 203.113.131.2; FPT c 210.245.0.11,...
Vy lm cch no c c tn min ca ring mnh (v d www.avrnet.vn)? Cu tr li l
phi ng k tn min (tr ph) v tr chi ph hng nm duy tr tn min. Lc ta c
quyn ch nh tn min tng ng vi a ch IP no.
Nu khng c iu kin mua tn min, ta c th s dng 1 s tn min min ph (v d ca
dyndns). l cch m ta s dng cho project ny (n phn cui cng nh).
Nguyn vn bi dinh_dong

Thy c th so snh Add lun l v Add MAC c khng ?


Ti sao trng MAC ch khi truyn ra internet li l a ch Gateway? gateway ging MAC

im no, m li c in vo MAC ch?


V ARP cache c ging vi bng NAT ip khng ? Em thy na l. C phi Gateway and local
IP(mng LAN) ca host s cho a ch MAC ca host ch khng ?
Mong thy tr li!
hiu v 2 loi a ch ta c th hnh dung nh th ny:
Gi s ta cn gi 1 bc th loanh quanh trong xm, ta ch cn ghi tn ngi nhn l c,
trong xm s d dng xc nh ng Nguyn Vn A ch no.
Tuy nhin khi gi th i trong phm vi c nc, nu ta ch ghi tn ngi nhn, thm ch c
thm c ngy thng nm sinh v s chng minh th bo m khng s b trng, th bu
in cng b tay v khng bit ng Nguyn Vn A u, v vi a ch ny (gm tn, ngy
thng nm sinh, s chng minh th) th d khng s trng a ch, th n cng khng th gip
ta xc nh c ng Nguyn Vn A ang tnh, thnh ph, ng no.
Vy ta cn mt cch ghi a ch khc, m nhn vo ta xc nh c ni cn chuyn th ti, v
d tnh... huyn.... ng.... s nh.
iu ny hon ton tng t vi a ch IP v a ch MAC: a ch MAC mc d l bo m
khng trng nhau, nhng nhn vo n ta khng th bit host c a ch MAC ang u?
M, Vit Nam hay Trung Quc,...? Do a ch MAC ch s dng c trong mng LAN, ni s
lng my tnh l t, cc thit b nh SWITCH c th bit ht cc a ch MAC trong mng.
gi d liu ra ngoi mng LAN, ta cn 1 loi a ch khc, mt a ch m khi nhn vo ta
bit ngay l host tng ng ang M hay Vit Nam, thm ch nu Vit Nam th thuc mng
ca nh cung cp dch v no. a ch tha mn yu cu ny chnh l a ch IP.
S d nh vy v trong a ch IP, ngi ta chia thnh 2 phn, phn u l a ch mng, cho
bit my tnh ang thuc mng no, phn sau l a ch host, gip phn bit cc my tnh
trong mng.
Ta c th d dng nhn thy iu ny: cc my tnh trong cng mng th phn u ca a ch
IP l ging nhau.
Nhn vo 1 a ch IP, ta s bit ngay my tnh tng ng ang nc no.
Trong phm vi mng LAN, vic chuyn d liu n ch v mt vt l hon ton ch cn da vo
HUB hay SWITCH, tuy nhin khi gi ra ngoi mng LAN th HUB hay SWITCH s b tay, v s
khng bit c a ch MAC ca my tnh bn ngoi. Lc ny, HUB hay SWITCH s chuyn gi
tin n mt thit b khc c kh nng a gi tin ra khi mng LAN, chnh l Gateway, thit
b kt ni gia mng LAN vi bn ngoi. V r rng SWITCH chuyn gi tin n Gateway, th
by gi a ch MAC ch trong frame ethernet phi l a ch MAC ca Gateway.
ARP cache hon ton khc bng NAT IP (NAT-Network Address Translation)
Trong project ny s hng dn n kt ni, ci t modem, ng k tn min, thit k
website,... ni chung t A-Z lun.
l mnh cn dng li gii thch r hn v hot ng ca 2 giao thc IP v ARP mt cht,
cng nh cc s dng 2 loi a ch IP v MAC trn mng, trc khi vit code tip, tuy hi di
dng 1 cht nhng s gip mi ngi hiu r hn cch thc lm vic ca TCP/IP, nh vy th s
d hiu code hn v c th t vit hay sa i code c d dng.
Ta hy xem xt 1 mng v d nh sau:
- Mng LAN ti nh gm 3 my tnh v 1 board mch ca chng ta kt ni vo ADSL router, t
ni vo mng ca nh cung cp dch v.
- Cc bn cng cn bit l thc ra modem ADSL hay ADSL router m ta dng nh, tht ra
bn trong n gm 3 thit b: mt HUB m rng s lng port, cho php nhiu my tnh c
th cng kt ni vo mng; mt Router IP ng vai tr Gateway, thc hin chc nng nh
tuyn gia mng bn trong (LAN) v mng bn ngoi (WAN); v cui cng l 1 modem
(Modulation - Demodulation) c th truyn d liu trn ng dy ADSL.

Ta x xem xt 2 v d:
V d A: board mch ca chng ta gi d liu n 1 my tnh trong cng mng LAN, v d l
my c a ch 192.168.1.6.
V d B: board mch gi d liu n 1 my tnh nm bn ngoi, v d l my c a ch
203.162.44.164
A-Trng hp gi trong mng LAN
Bc 1: Giao thc IP trong board mch nhn c yu cu gi d liu n a ch IP
192.168.1.6
Bc 2: N i hi giao thc ARP (thng qua hm ArpIpOut) v a ch ny. ARP sau khi tm
trong bng ARP cache khng thy, n s gi 1 bn tin ARP request di hnh thc broadcast
n mi my tnh trong mng. My tnh c a ch tng ng s tr li.

Bc 3: ARP s cp nht bng ARP cache v tr li li cho giao thc IP.


Bc 4: giao thc IP dng thng tin ny in vo frame ethernet v chuyn sang giao th
ethernet gi i.

B-Trng hp gi ra ngoi mng LAN


Nu vn lm theo cch c th s xy ra trng hp nh sau:

Nh vy, nu vn lm theo cch c, vic gi d liu s tht bi.


Mi vic phi c tin hnh nh sau:

C ai bit cch post flash ln forum khng? Xin ch gip. Vi minh ha bng nh ng c l d
hiu hn.
Vy by gi ta bt u vit code cho cc giao thc ip v arp:
Ta to file ip.c vi ni dung ban u
Code:
//---------------------------------------------------------------------------// Writen by NTTam - PTITHCM
//---------------------------------------------------------------------------#include <avr/io.h>
#include "packet.h"
#include "ethernet.h"
#include "arp.h"
#include "ip.h"

V file header ip.h


Code:
//---------------------------------------------------------------------------// Writen by NTTam - PTITHCM
//---------------------------------------------------------------------------#ifndef IP_H
#define IP_H
#endif //IP_H

Ta cng to 2 file tng ng cho giao thc ARP:


arp.c
Code:

//---------------------------------------------------------------------------// Writen by NTTam - PTITHCM


//---------------------------------------------------------------------------#include <avr/io.h>
#include "packet.h"
#include "ethernet.h"
#include "arp.h"
#include "ip.h"

arp.h
Code:
//---------------------------------------------------------------------------// Writen by NTTam - PTITHCM
//---------------------------------------------------------------------------#ifndef ARP_H
#define ARP_H
//---------------------------------------------------------------------------#endif //ARP_H

Nh ta thy trn, giao thc IP hot ng, n cn bit mt s thng tin c bn:
- a ch IP ca n.
- Subnet Mask ca n (c thi gian se gii thch Subnet mask sau).
- a ch IP ca Gateway.
- a ch MAC ca n.
Ta s lu cc thng tin ny trong mt bin kiu struct l ipConfig. M file ip.h, khai bo kiu
struct ny vo:
Code:
//---------------------------------------------------------------------------#include "packet.h"
struct ipConfig
{
unsigned long ip;
unsigned long netmask;
unsigned long gateway;
struct ntEthAddr ethaddr;
};

///< IP addressing/configuration structure


///< IP address
///< netmask
///< gateway IP address

M tip file ip.c, khai bo bin IpMyConfig c kiu l struct ipConfig


Code:
//-------------------------------------------------------------------------------------struct ipConfig IpMyConfig;
///< Local IP address/config structure

Tip theo ta vit trong file ip.c mt s hm chc nng cho giao thc ny:
u tin l hm tnh trng kim tra li (checksum) trong Header IP. Nu cc bn xem li
phn cu trc Header ca IP s thy n c 1 trng kim tra li cho Header (khng bao gm
data). Trng ny gip pha nhn gi IP kim tra li xem thng tin cha trong Header (rt quan
trng) c b sai trong qu trnh truyn hay khng. Nu c sai st, gi tin s b hy b m
khng x l.
Pha pht trc khi gi phi tnh gi tr checksum v ghi n vo trng checksum trong header.
Pha thu khi nhn gi tin s t mnh tnh li check sum 1 cch c lp, sau so snh vi
checksum m pha pht tnh (lu trong header) nu c khc bit th tc l c li xy ra, v
gi tin s b hy.
Vy hm ny s c giao thc IP s dng c khi gi v nhn gi tin.
Code:

//-------------------------------------------------------------------------------------//Ham tinh checksum cho goi ip


unsigned int ipChecksum(unsigned char *data, unsigned int len)
{
register unsigned long sum = 0;
for (;;) {
if (len < 2)
break;
sum += *((unsigned int *)data);
data+=2;
len -= 2;
}
if (len)
sum += *(unsigned char *) data;
while ((len = (unsigned int) (sum >> 16)) != 0)
sum = (unsigned int) sum + len;
return (unsigned int) sum ^ 0xFFFF;
}

Ngoi l 1 t: khi lp trnh project ny, vit n phn tnh checksum mnh tnh sai, dn n
gi IP khng hp l. Phi dng phn mm Wireshark bt tng gi tin, kim tra li tng bit v
tnh li checksum bng tay sa, mt chng 4 ting cho ring phn checksum ny.
Tip theo l hm set cc gi tr trong struct ipConfig:
Code:
//-------------------------------------------------------------------------------------//Set cac gia tri cau hinh cho giao thuc ip
void ipSetConfig(unsigned long myIp, unsigned long netmask, unsigned long gatewayIp)
{
/*
// set local addressing
IpMyConfig.ip = myIp;
IpMyConfig.netmask = netmask;
IpMyConfig.gateway = gatewayIp;
ethGetMacAddress(IpMyConfig.ethaddr.addr);
*/
struct ntEthAddr ethaddr;
// set local addressing
IpMyConfig.ip = myIp;
IpMyConfig.netmask = netmask;
IpMyConfig.gateway = gatewayIp;
// set ARP association
ethGetMacAddress(ethaddr.addr);
arpSetAddress(&ethaddr, myIp);
}

Hm tr li bin con tr n struct lu thng tin config cho IP, hm ny nhm gip cc module
khc truy xut c ti bin ipConfig thuc module ip.
Code:
//-------------------------------------------------------------------------------------//Tra lai con tro den struct ipConfig
struct ipConfig* ipGetConfig(void)
{
return &IpMyConfig;

Hm in ra a ch MAC (dng trong debug hoc khi config board mch qua cng ni tip bng
command line.
Code:
//-------------------------------------------------------------------------------------//In ra dia chi ethernet
void ethPrintAddr(struct ntEthAddr* ethAddr)
{
printf("%x:%x:%x:%x:%x:%x",(ethAddr->addr[0]),(ethAddr->addr[1]),(ethAddr>addr[2]),\
(ethAddr->addr[3]),(ethAddr->addr[4]),(ethAddr->addr[5]));
}

Tng t l hm in ra a ch IP
Code:
//-------------------------------------------------------------------------------------//In ra dia chi IP
void ipPrintAddr(unsigned long ipaddr)
{
printf("%d.%d.%d.%d",
((unsigned char*)&ipaddr)[3],
((unsigned char*)&ipaddr)[2],
((unsigned char*)&ipaddr)[1],
((unsigned char*)&ipaddr)[0]);
}

V hm in ra cc thng s cu hnh IP
Code:
//-------------------------------------------------------------------------------------//In ra cac gia tri cau hinh cho giao thuc IP
void ipPrintConfig(struct ipConfig* config)
{
printf("IP Addr : "); ipPrintAddr(config->ip);
printf("\n\r");
printf("Netmask : "); ipPrintAddr(config->netmask);
printf("\n\r");
printf("Gateway : "); ipPrintAddr(config->gateway);
printf("\n\r");
}

Lu : truy xut c cc hm trong module ethernet.c, chng ta phi thm phn khai
bo (declare) cc hm ny vo file header tng ng ethernet.h nh. T nay vic ny l
ng nhin, mnh s khng nhc li na.
Ta c s dng hm printf xut d liu ra cng COM, cc bn t vit nh.
Mt s hm thuc module giao thc ARP, ta vn cha vit, c gi y, nn s to thng
bo li thiu hm khi bin dch.
Trn y l mt s hm cng c cung cp cc chc nng h tr cho giao thc IP. Tip theo s l
nhng hm x l chnh trong giao thc IP, bao gm hm gi v nhn gi tin IP.
Ta vit tip hm thc hin gi 1 gi tin qua giao thc IP:
Code:
//-------------------------------------------------------------------------------------//Ham gui 1 goi IP
void ipSend(unsigned long dstIp, unsigned char protocol, unsigned int len, unsigned char*
ipData)
{

struct ntEthHeader* ethHeader;


struct ntIPHeader* ipHeader;
ipHeader = (struct ntIPHeader*)(ipData - IP_HEADER_LEN);
ethHeader = (struct ntEthHeader*)(ipData - IP_HEADER_LEN - ETH_HEADER_LEN);
len += IP_HEADER_LEN;
ipHeader->desIPAddr = HTONL(dstIp);
ipHeader->srcIPAddr = HTONL(IpMyConfig.ip);
ipHeader->Protocol = protocol;
ipHeader->Len = HTONS(len);
ipHeader->verHdrLen = 0x45;
ipHeader->ToS = 0;
ipHeader->IDNumber = 0;
ipHeader->Offset = 0;
ipHeader->TTL = IP_TIME_TO_LIVE;
ipHeader->Checksum = 0;
ipHeader->Checksum = ipChecksum((unsigned char*)ipHeader, IP_HEADER_LEN);
if( (dstIp & IpMyConfig.netmask) == (IpMyConfig.ip & IpMyConfig.netmask) )
{
arpIpOut((unsigned char*)ethHeader,0);
// local send
}
else
{
arpIpOut((unsigned char*)ethHeader,IpMyConfig.gateway);
// gateway
send
}
len += ETH_HEADER_LEN;
#ifdef IP_DEBUG
printf("Sending IP packet\r\nAddr: ");
ipPrintAddr(dstIp);printf("\n\rMAC: ");
ethPrintAddr(&(ethHeader->desAddr));
#endif
ethSendFrame(len, (unsigned char*)ethHeader);
}

Gii thch:
- Khi hm ny c gi, c ngha l giao thc lp trn (TCP hay UDP) chun b sn d liu
cn gi i (phn data ca gi IP) v t ln buffer (ethernet buffer). Vy trong hm ny ta cn
in y thng tin to nn Header IP v gi hm ca giao thc ethernet (ethSendFrame)
yu cu giao thc ethernet gi gi tin ny i.
- Nh vy phn u, ta tr 2 bin con tr c kiu l IP Header v Ethernet Header n cc v
tr tng ng trn buffer. Sau ln lt tnh ton v in cc gi tr ca cc trng trong
Header IP vo.
- Tip theo ta gi giao thc ARP phn gii a ch. Lc ny s c 2 trng hp: nu a ch
mng trong a ch IP ch ging ca chng ta, tc l host ch nm trong cng mng LAN, ta
s yu cu ARP tm a ch MAC ch in vo frame ethernet v gi i (hm ArpIpOut). Nu
khc a ch mng, tc l host ch nm bn ngoi mng LAN, ta s yu cu ARP tm a ch
MAC ca gateway v in vo frame ethernet.
- Sau ta gi hm ca giao thc ethernet gi d liu i.
Trong hm ny, ta c s dng 1 gi tr l TTL (Time To Live) in vo trng TTL trong
Header IP (xem li cu trc Header IP). Gi tr ny cn c nh ngha trc. Ta thm nh
ngha ny vo file ip.h:
Code:
#define IP_TIME_TO_LIVE
cho header IP

128

//gia tri Time-To-Live (TTL) mc nh

C thi gian s gii thch ngha ca trng TTL sau nh.


V hm x l khi nhn c 1 gi tin IP:
Code:
//-------------------------------------------------------------------------------------//Ham xu ly goi IP, duoc goi boi giao thuc ethernet khi paket type duoc xac dinh la IP
void IPProcess(unsigned int len, struct ntIPHeader* packet)
{
// check IP addressing, stop processing if not for me and not a broadcast
if( (HTONL(packet->desIPAddr) != ipGetConfig()->ip) &&
(HTONL(packet->desIPAddr) != (ipGetConfig()->ip|ipGetConfig()->netmask))
&&
(HTONL(packet->desIPAddr) != 0xFFFFFFFF) )
return;
// handle ICMP packet
if( packet->Protocol == IP_PROTO_ICMP )
{
#ifdef IP_DEBUG
printf("IP->Rx: ICMP/IP packet\r\n");
//icmpPrintHeader((icmpip_hdr*)packet);
#endif
icmpIpIn((struct ntIPHeader*)packet);
}
else if( packet->Protocol == IP_PROTO_UDP )
{
#ifdef IP_DEBUG
printf("IP->Rx: UDP/IP packet\r\n");
//debugPrintHexTable(NetBufferLen-14, &NetBuffer[14]);
#endif
UDPProcess(len, ((struct ntIPHeader*)packet) );
}
else if( packet->Protocol == IP_PROTO_TCP )
{
#ifdef IP_DEBUG
printf("IP->Rx: TCP/IP packet\r\n");
#endif
TCPProcess((unsigned char *)packet,len-((packet->verHdrLen & 0x0F)<<2));
}
else
{
#ifdef IP_DEBUG
printf("IP->Rx: IP packet\r\n");
#endif
}
}
//--------------------------------------------------------------------------------------

Gii thch:
- Khi nhn c 1 gi IP, vic u tin giao thc IP cn lm l kim tra li a ch IP xem c
phi l gi cho mnh khng: v ta ch nhn nu ng a ch hoc a ch l IP broadcast (lu
y l a ch IP broadcast (255.255.255.255) nh, khng phi MAC broadcast).
- Mc d trc , giao thc ethernet kim tra a ch MAC ri, nhng giao thc IP vn kim
tra li a ch IP.
- Tip theo, ta kim tra trng protocol trong header IP xem giao thc lp trn (trn giao
thc IP) no gi gi tin ny (TCP, UDP, hay ICMP) v gi hm ca giao thc tng ng x
l.
Vy l xong giao thc IP.

Tip theo ta vit code cho giao thc ARP.


Trc ht ta cn xc nh mt s gi tr hng dnh cho giao thc ARP. l s dng ti a
trong bng ARP cache, thi gian timeout cho mi cp a ch trong bng ARP cache.
Ta m file arp.h thm vo cc nh ngha ny:
Code:
//-------------------------------------------------------------------------------------#include "packet.h"
//-------------------------------------------------------------------------------------#ifndef ARP_TABLE_SIZE
#define ARP_TABLE_SIZE
8
#endif
#ifndef ARP_CACHE_TIME_TO_LIVE
#define ARP_CACHE_TIME_TO_LIVE
#endif

250

Ta cng khai bo trong arp.h mt bin kiu struct cho mi dng trong bng ARP cache, gm 1
a ch IP v a ch MAC tng ng vi a ch IP :
Code:
//-------------------------------------------------------------------------------------struct ARPentry
{
unsigned long ipAddr;
///< remote-note IP address
struct ntEthAddr ethAddr; ///< remote-node ethernet (hardware/mac) address
unsigned char time;
///< time to live (in ARP
table); this is decremented by arpTimer()
};

Trong mi entry, cn c thm 1 bin l timeout. Nh ni phn trc, mi entry trong ARP
cache khng tn ti mi c 1 thi gian timeout nht nh, bin timeout ny s c gn 1 gi
tr ban u mi khi c cp nht, v s t ng gim theo thi gian (nh s dng ngt timer).
Nu 1 entry qu lu m khng c cp nht (bin timeout gim v 0) th n s b xa i (thc
ra ta khng cn xa m ch cn xem cc entry c bin timeout = 0 l entry trng).
Ta quay li file arp.c, khai bo mt ARPentry lu cp a ch IP a ch MAC ca chnh
board mch v mt array ca ARPentry lm bng ARP cache:
Code:
//-------------------------------------------------------------------------------------struct ARPentry ARPMyAddr;
struct ARPentry ARPTable[ARP_TABLE_SIZE];

Tip theo ta vit cc hm cho giao thc ARP:


u tin l hm khi to giao thc ARP (thc cht l khi ng gi tr cc bin trong ARP cache
m thi):
Code:
//-------------------------------------------------------------------------------------void arpInit(void)
{
unsigned char i;
for(i=0; i<ARP_TABLE_SIZE; i++)
{
ARPTable[i].ipAddr = 0;
ARPTable[i].time = 0;
}
}

Hm set a ch, thc ra ch l khai bo a ch MAC v IP ca bn thn cho ARP:


Code:
//-------------------------------------------------------------------------------------void arpSetAddress(struct ntEthAddr* ethAddr, unsigned long ipAddr)
{
ARPMyAddr.ethAddr = *ethAddr;
ARPMyAddr.ipAddr = ipAddr;
}

Hm tm kim 1 a ch IP trong bng ARP cache, tr li v tr ca entry tng ng vi a ch IP


trong bng ARP cache:
Code:
//-------------------------------------------------------------------------------------unsigned char arpSearchIP(unsigned long ipaddr)
{
unsigned char i;
for(i=0; i<ARP_TABLE_SIZE; i++)
{
if((ARPTable[i].ipAddr == ipaddr) && (ARPTable[i].time != 0))
{
return i;
}
}
return -1;
}

Hm cp nht 1 entry trong bng ARP


Code:
//-------------------------------------------------------------------------------------void arpUpdateEntry(struct ntEthAddr ethAddr,unsigned long ipAddr)
{
unsigned char index;
index = arpSearchIP(ipAddr);
if(index < ARP_TABLE_SIZE)
{
ARPTable[index].ethAddr = ethAddr;
ARPTable[index].time = ARP_CACHE_TIME_TO_LIVE;
#ifdef ARP_DEBUG
printf("Update ARP TTL %d: ",index);ipPrintAddr(ipAddr);
printf("-");ethPrintAddr(&ethAddr);printf("\n\r");
#endif
return;
}
for(index=0; index<ARP_TABLE_SIZE; index++)
{
if(!ARPTable[index].time)
{
ARPTable[index].ethAddr = ethAddr;
ARPTable[index].ipAddr = ipAddr;
ARPTable[index].time = ARP_CACHE_TIME_TO_LIVE;
#ifdef ARP_DEBUG
printf("Update ARP: ");ipPrintAddr(ipAddr);
printf("-");ethPrintAddr(&ethAddr);printf("\n\r");
#endif
return;
}
}
}

Hm x l khi nhn c 1 bn tin ARP (do lp giao thc ethernet chuyn n):

Code:
//-------------------------------------------------------------------------------------void arpArpProcess(unsigned int len, unsigned char* ethFrame)
{
struct ntEthHeader* ethHeader;
struct ntARPHeader* arpHeader;
ethHeader = (struct ntEthHeader*)ethFrame;
arpHeader = (struct ntARPHeader*)(ethFrame + ETH_HEADER_LEN);
#ifdef ARP_DEBUG
printf("Received ARP Request\r\n");
arpPrintHeader(arpHeader);
#endif
if(
(arpHeader->hwType == 0x0100) &&
(arpHeader->protocol == 0x0008) &&
(arpHeader->hwLen == 0x06) &&
(arpHeader->protoLen == 0x04) &&
(arpHeader->dipaddr == HTONL(ARPMyAddr.ipAddr))){
if(arpHeader->opcode == HTONS(ARP_OPCODE_REQUEST)){
arpUpdateEntry(arpHeader->shwaddr,HTONL(arpHeader->sipaddr));
arpHeader->dhwaddr = arpHeader->shwaddr;
arpHeader->dipaddr = arpHeader->sipaddr;
arpHeader->shwaddr = ARPMyAddr.ethAddr;
arpHeader->sipaddr = HTONL(ARPMyAddr.ipAddr);
arpHeader->opcode = HTONS(ARP_OPCODE_REPLY);
ethHeader->desAddr = ethHeader->srcAddr;
ethHeader->srcAddr = ARPMyAddr.ethAddr;
#ifdef ARP_DEBUG
printf("Sending ARP Reply\r\n");
arpPrintHeader(arpHeader);
#endif
ethSendFrame(len, (unsigned char*)ethHeader);
return;
}
if(arpHeader->opcode == HTONS(ARP_OPCODE_REPLY)){
arpUpdateEntry(arpHeader->shwaddr,HTONL(arpHeader->sipaddr));
#ifdef ARP_DEBUG
printf("is ARP reply\r\n");
#endif
return;
}
}
#ifdef ARP_DEBUG
printf("Unknown ARP packet\r\n");
#endif
}

hm x l khi nhn c 1 gi IP: nh ni trc y trong ni dung v ARP, c 2 cch cp


nht ARP l thng qua ARP request v thng qua cc gi IP n. Mi khi c 1 gi IP n, l
d nhin l gi ny s c giao thc IP x l, ARP khng can thip vo qu trnh x l . Tuy
nhin trong mi gi IP n c 2 thng tin quan trng m ARP cn: l a ch IP v a ch
MAC ca host gi gi tin . ARP s dng cp a ch ny cp nht ARP cache.
Code:
//-------------------------------------------------------------------------------------void arpIPPacketIn(unsigned char* ethFrame)
{
struct ntEthHeader* ethHeader;
struct ntIPHeader* ipHeader;
ethHeader = (struct ntEthHeader*)ethFrame;
ipHeader = (struct ntIPHeader*)(ethFrame + ETH_HEADER_LEN);
arpUpdateEntry(ethHeader->srcAddr,HTONL(ipHeader->srcIPAddr));
}
//--------------------------------------------------------------------------------------

Cui cng l hm phn gii a ch cung cp a ch MAC cho giao thc IP khi c yu cu
Code:
void arpIpOut(unsigned char* ethFrame, unsigned long phyDstIp)
{
unsigned char index;
struct ntEthHeader* ethHeader;
struct ntIPHeader* ipHeader;
ethHeader = (struct ntEthHeader*)ethFrame;
ipHeader = (struct ntIPHeader*)(ethFrame + ETH_HEADER_LEN);
if(phyDstIp)
index = arpSearchIP(phyDstIp);
else
index = arpSearchIP(HTONL(ipHeader->desIPAddr));
if(index < ARP_TABLE_SIZE)
{
ethHeader->srcAddr = ARPMyAddr.ethAddr;
ethHeader->desAddr = ARPTable[index].ethAddr;
ethHeader->type = HTONS(ETH_TYPE_IP);
}
else
{
ethHeader->srcAddr = ARPMyAddr.ethAddr;
ethHeader->desAddr.addr[0] = 0xFF;
ethHeader->desAddr.addr[1] = 0xFF;
ethHeader->desAddr.addr[2] = 0xFF;
ethHeader->desAddr.addr[3] = 0xFF;
ethHeader->desAddr.addr[4] = 0xFF;
ethHeader->desAddr.addr[5] = 0xFF;
ethHeader->type = HTONS(ETH_TYPE_IP);
}
#ifdef ARP_DEBUG
printf("ARP Result:");
ipPrintAddr(ARPTable[index].ipAddr);printf("-");
ethPrintAddr(&(ethHeader->desAddr));printf("\r\n");
#endif
}

Trong hm ArpIpOut trn, c 1 ch "lch lut", khng tun th ng nguyn tc lm vic ca


ARP, cc bn tm ra, nu c ai tm ra mnh s gii thch ti sao li lm nh vy.
Hm kim tra timeout ca cc entry trong ARP cache. hm ny s c gi nh k bi ngt
timer kim tra xem c entry no "qu date" hay khng, v hy cc entry .
Code:
//-------------------------------------------------------------------------------------void arpTimer(void)
//Goi moi 10s
{
int index;
for(index=0; index<ARP_TABLE_SIZE; index++)
{
if(ARPTable[index].time)
ARPTable[index].time--;
}
}
//--------------------------------------------------------------------------------------

Cc hm phc v cho mc ch debug:


Code:
#ifdef ARP_DEBUG
void arpPrintHeader(struct ntARPHeader* packet)

{
printf("ARP Packet:\r\n");
printf("Operation
: ");
if(packet->opcode == HTONS(ARP_OPCODE_REQUEST))
printf("REQUEST");
else if(packet->opcode == HTONS(ARP_OPCODE_REPLY))
printf("REPLY");
else
printf("UNKNOWN");
printf("\n\r");
printf("SrcHwAddr
: "); ethPrintAddr(&packet->shwaddr);printf("\n\r");
printf("SrcProtoAddr: "); ipPrintAddr(HTONL(packet->sipaddr));printf("\n\r");
printf("DstHwAddr
: "); ethPrintAddr(&packet->dhwaddr);printf("\n\r");
printf("DstProtoAddr: "); ipPrintAddr(HTONL(packet->dipaddr));printf("\n\r");
}
//-------------------------------------------------------------------------------------void arpPrintTable(void)
{
unsigned char i;
// print ARP table
printf("Time
Eth Address
IP Address\r\n");
printf("---------------------------------------\r\n");
for(i=0; i<ARP_TABLE_SIZE; i++)
{
printf("%d",(ARPTable[i].time));
printf("
");
ethPrintAddr(&ARPTable[i].ethAddr);
printf(" ");
ipPrintAddr(ARPTable[i].ipAddr);
printf("\n\r");
}
}
#endif
//--------------------------------------------------------------------------------------

Sau khi vit hm xong, nh thm declare vo file header tng ng nh.
n y l xong giao thc IP v ARP, trong phn ny c gi cc hm ca giao thc TCP, UDP v
ICMP m ta vn cha vit ti, nn dch cng s b bo li thiu 3 hm ny nh.

Bi 5: Cc giao thc lp vn chuyn


Vy l xong cc giao thc lp 3, IP v giao thc h tr cho n l ARP. By gi chng ta s
chuyn sang cc giao thc lp 4, lp vn chuyn (Transport Layer). l TCP (Transport
Control Protocol) v UDP (User Datagram Protocol), ngoi ra cn c mt giao thc iu khin
cng c th xp vo y, l ICMP (Internet Control Message Protocol).
Trc ht ta ni qua v chc nng v hot ng c bn ca cc giao thc ny trc khi bt tay
vo vit code.
Nu ni phn lp trnh giao thc IP phc tp gp i so vi ethernet th c l lp trnh giao thc
TCP phi phc tp gp i c IP v ARP cng li. V trong giao thc TCP, ta phi x l cc vn
lin quan n qu trnh bt tay gia hai pha khi truyn d liu. Phi h tr cng lc nhiu
kt ni TCP n cc host khc (v d webserver phi c kh nng x l khi c ng thi vi ba
my tnh cng truy cp vo website), v lin quan cht ch n lp ng dng v dch v. Chnh
v vy ta phi tm hiu k hot ng ca n.

So vi TCP th UDP n gin hn nhiu.


Cn ICMP l mt giao thc dng chuyn qua li cc bn tin iu khin trn mng. V d khi
ta g lnh ping trn my tnh, s c 1 bn tin iu khin l ICMP request c gi n a ch
ch. V ni nhn c ICMP request s tr li li bng bn tin ICMP reply. Nu vit xong giao
thc ny th chng ta c th ping n board mch ca chng ta c ri.
C l ta bt u vi giao thc ICMP.
Giao thc thng ip iu khin Internet (Internet Control Message Protocol) c cc router
v host trn mng Internet s dng thng bo v cc vn gp phi trong qu trnh nh
tuyn d liu.
Vic ny c thc hin bng cch gi qua li cc bn tin thng bo v cc s kin xy ra trn
mng. Cc bn tin ny c gi l thng ip iu khin Internet (Internet Control Message).
C rt nhiu bn tin nh vy, c dng trong nhng trng hp c th khc nhau. Di y l
1 s bn tin ICMP thng gp:
- Bn tin Echo Request v Echo Reply: s dng cho qu trnh kim tra (lnh ping).
- Bn tin Source Quench: yu cu host ngun gim tc truyn d liu.
- Bn tin Destination Unreachable: thng bo cho host ngun bit datagram khng th
chuyn c n ch.
- Bn tin Time Exceeded: thng bo 1 gi tin b hy do TTL = 0.
- Bn tin Fragmentation Needed: thng bo cho host ngun bit 1 datagram c c DF (Dont
Fragment) = 1, nhng router cn phn on datagram ny chuyn n chng k tip.
Trong phm vi project ny, chng ta ch lp trnh cho 2 bn tin l Echo Request v Echo
Reply phc v cho vic ping n board mch ca chng ta.
y l cu trc ca bn tin ICMP:

Bn tin ICMP gm 8 byte:


- Byte u l trng Type: cho bit y l bn tin g.
- Byte th 2 l Code: cho bit m c th cho tng trng hp.
- 2 byte k l checksum: kim tra li.
- 4 byte cn li cha thng tin ring ca tng loi bn tin. Trong trng hp bn tin Echo
Request v Echo Reply th y l s nhn dng (ID) v s tun t ca bn tin.
Vy ta cn khai bo cu trc ca bn tin ICMP vo trong file packet.h:
Code:
//-------------------------------------------------------------------------------------//Cau truc ICMP header
struct ntICMPHeader
{
unsigned char
Type;
unsigned char
Code;
unsigned int
Checksum;
unsigned int
ID;
unsigned int
seqNumber;

};
#define ICMP_HEADER_LEN 8
#define ICMP_TYPE_ECHOREPLY
#define ICMP_TYPE_ECHOREQUEST

0
8

Tip theo ta to file source v file header cho module giao thc ICMP.
Ni dung ban u ca file icmp.c
Code:
//---------------------------------------------------------------------------// Writen by NTTam - PTITHCM
//---------------------------------------------------------------------------#include "packet.h"
#include "ethernet.h"
#include "arp.h"
#include "ip.h"
#include "icmp.h"

V file icmp.h
Code:
//---------------------------------------------------------------------------// Writen by NTTam - PTITHCM
//---------------------------------------------------------------------------//======================================================================================
//
icmp.h
//======================================================================================
//
This is header file for icmp.c
//
Writen by NTTam
//
PTITHCM
//
Ver 1.0
//======================================================================================
#ifndef ICMP_H
#define ICMP_H
//-------------------------------------------------------------------------------------#include "packet.h"
//-------------------------------------------------------------------------------------#endif //ICMP_H

By gi ta bt tay vo vit code:


u tin l hm x l khi nhn c bn tin Echo Request (tc l c my tnh ping n
board mch.
Code:
//-------------------------------------------------------------------------------------//Ham xu ly goi ICMP nhan duoc
void icmpIpIn(struct ntIPHeader* ipHeader)
{
struct ntICMPHeader* icmpHeader;
icmpHeader = (struct ntICMPHeader*)((unsigned char*)ipHeader + IP_HEADER_LEN);
// check ICMP type
switch(icmpHeader->Type)
{
case ICMP_TYPE_ECHOREQUEST:
// echo request
icmpEchoReply(ipHeader);
break;
default:
break;
}
}

Chc nng hm ny kh n gin: ta kim tra trng Type xem y c ng l bn tin


Echo Request hay khng. Nu ng ta gi hm icmpEchoReply (s vit k tip) tr li.
Tip theo l hm icmpEchoReply gi bn tin Echo Reply tr li cho bn tin Echo
Request
Code:
//-------------------------------------------------------------------------------------//Ham gui di ban tin tra loi cho Echo Request (Echo Reply)
void icmpEchoReply(struct ntIPHeader* ipHeader)
{
unsigned long tempIp;
unsigned char* ethFrame;
struct ntICMPHeader* icmpHeader;
icmpHeader = (struct ntICMPHeader*)((unsigned char*)ipHeader + IP_HEADER_LEN);
icmpHeader->Type = ICMP_TYPE_ECHOREPLY;
icmpHeader->Checksum = 0;
icmpHeader->Checksum = ipChecksum((unsigned char*)icmpHeader, HTONS(ipHeader>Len)-IP_HEADER_LEN);
tempIp = ipHeader->desIPAddr;
ipHeader->desIPAddr = ipHeader->srcIPAddr;
ipHeader->srcIPAddr = tempIp;
ethFrame = ((unsigned char*)ipHeader);
ethFrame -= ETH_HEADER_LEN;
arpIpOut(ethFrame, 0);
#ifdef ICMP_DEBUG
icmpPrintHeader(ipHeader);
#endif
ethSendFrame(HTONS(ipHeader->Len)+ETH_HEADER_LEN, ethFrame);
}

Ni dung thc hin trong hm ny kh n gin:


- Ta in cc ni dung cn thit cho bn tin Echo Reply.
- Gi giao thc ARP phn gii a ch
- Gi hm ethSendFrame ca giao thc ethernet gi frame ethernet i.
Cui cng l 1 hm dng cho mc ch debug:
Code:
//-------------------------------------------------------------------------------------#ifdef ICMP_DEBUG
//In ra Header cua goi ICPM
void icmpPrintHeader(struct ntIPHeader* ipHeader)
{
struct ntICMPHeader* icmpHeader;
icmpHeader = (struct ntICMPHeader*)((unsigned char*)ipHeader + IP_HEADER_LEN);
printf("ICMP Packet:\r\n");
// print source IP address
printf("SrcIpAddr: ");
ipPrintAddr(HTONL(ipHeader->srcIPAddr));
printf("\n\r");
// print dest IP address
printf("DstIpAddr: ");
ipPrintAddr(HTONL(ipHeader->desIPAddr));
printf("\n\r");
// print type
printf("Type
: ");
switch(icmpHeader->Type)
{
case ICMP_TYPE_ECHOREQUEST:
printf("ECHO REQUEST"); break;
case ICMP_TYPE_ECHOREPLY:
printf("ECHO REPLY"); break;
default:
printf("UNKNOWN"); break;
}
printf("\n\r");
// print code

printf("Code: 0x%x \n\r",(unsigned int)(icmpHeader->Code));


}
#endif
//--------------------------------------------------------------------------------------

Ta cng phi nh thm declare cc hm va vit vo file header (icmp.h):


Code:
void icmpIpIn(struct ntIPHeader* ipHeader);
void icmpEchoReply(struct ntIPHeader* ipHeader);
void icmpPrintHeader(struct ntIPHeader* ipHeader);

Vy l xong giao thc ICMP.


n y vn cha ping c nh, v ta vn cha vit ngt timer phc v cho cc hm kim
tra thi gian timeout v ni dung cho chng trnh chnh (main()).
Giao thc TCP (Transport Control Protocol):
Tip theo l giao thc kh chu nht trong chng giao thc TCP/IP. chnh l giao thc TCP
(Transport Control Protocol)
Nhim v chnh ca TCP l m bo d liu n ch ng v trn mt mi trng truyn ti
khng ng tin cy (IP).
hiu chc nng v cch m TCP thc hin chc nng , ta xem minh ha sau y:

n y c 3 trng hp xy ra:

- TH 1: mi vic sun s, th k bn B nhn c th, gi th tr li bo nhn c thng


ip. Th k bn A s hy bn photo cn lu d, vic gi thng ip thnh cng.
- TH2: bu in lm mt th, bn B khng nhn c. Nh vy th k bn A ch 1 thi gian
khng thy phn hi s ly bn photo ra gi li ln na.
- TH 3: th k bn B nhn c v gi th bo nhn, nhng bu in li lm tht lc th
ny. Th k bn A c mt thi gian khng thy cng s gi li. Khi bn B nhn c thng
ip mt ln na cng s gi bo nhn mt ln na.
Cu trc Header TCP:

Ch thch:
- S port ch v s port ngun: phn bit cc tin trnh ng dng ang xy ra trong my
tnh
- Cc s sequence v Acknowledgement: s sequence phn bit cc segment khc nhau
trong mt dng d liu, cc s Acknowledgement dng trong c ch xc nhn
- Vng Data offset: chiu di ca Header tnh theo n v 32 bit
- Mt s c (flags):
. URG (Urgent): thit lp 1 khi c d liu quan trng cn truyn ngay.
. ACK: cho bit c s xc nhn nm trong vng Acknowledgement
. PSH (Push): c thit lp trong trng hp d liu nn c giao tc thi
. RST (Reset): ch th mt li sai v hy b phin lm vic
. SYN (Synchronize): trong cc bn tin khi to khi thit lp mt kt ni truyn d liu
. FIN (Finish): dng ng 1 phin lm vic
- Vng Window: ch ra s lng khng gian b m kh dng nhn d liu
- Vng Checksum: vng kim tra sai cho c segment
- Vng Urgent Pointer: ch ra chiu di ca d liu urgent
- Vng Options: xc nh kch thc cc i ca 1 segment
C th hn, vai tr ca TCP trong chng giao thc TCP gm 3 chc nng chnh: iu khin
lung, kim sot li v bo nhn.
- iu khin lung: iu phi tc v kch thc lung d liu m bo pha nhn kh

nng nhn v x l lung d liu.


- Kim sot li: m bo cc gi tin n ng v
- Bo nhn: khi nhn c d liu v khng c li, pha nhn phi bo li vi pha gi bit.
thc hin c cc chc nng , mt qu trnh truyn d liu qua giao thc TCP (m ta gi
l phin truyn thng session) gm c 3 giai on:
- Thit lp kt ni
- Truyn d liu
- Gii ta kt ni
c th hnh dung c qu trnh , mi cc bn xem minh ha sau:
Thit lp kt ni:

Truyn d liu:

Gii ta kt ni:

By gi ta lin h vi cc trng trong TCP Header nh:

c th gim st cht ch trng thi v mi s kin xy ra trong 1 kt ni TCP, trng thi ca


mt kt ni TCP c chuyn i tun theo mt lu trng thi nh sau:

y chnh l thut ton chnh m ta phi lp trnh cho giao thc TCP. Nhn thy s cha

Gii thch:
- TCP l giao thc hng kt ni, dng client server. Tc l trong 1 phin truyn thng th s
c mt pha ng vai tr client (chnh l pha khi to kt ni, trong v d minh ha trn l cng
ty A, bn tri), pha cn li, lc no cng trng thi ch i cc client thit lp kt ni ti
chnh l server.
- V d khi ta truy cp web, th my tnh ca ta l client, my ch cha trang web chnh l
server, lc no cng trng thi i cc my tnh client kt ni n (v phi c kh nng thit
lp ng thi nhiu kt ni, v c th c nhiu client kt ni ti cng lc).
- i vi mch m chng ta nh lm, d nhin l thng thng n ng vai tr server ri.
- Trong lu trn, p dng cho c client v server. C client v server u bt u bng trng
thi Close. Client s thit lp kt ni theo con ng Active Open (n ch ng thit lp kt
ni). Server s thit lp kt ni theo con ng Passive Open (th ng, v n i client bt
u m)
Qu trnh chuyn trng thi: ta hy xem xt kch bn thng thng nht.
- C hai bt u bng trng thi close, khng c kt ni no tn ti.
- Khi Server m mt port TCP i client thit lp kt ni, n chuyn sang trng thi Listen.
- Khi client gi i bn tin SYN (bc s 1 trong v d minh ha, giai on thit lp kt ni), n
chuyn sang trng thi SYN sent.
- Lc ny khi server nhn c bn tin SYN t client v gi p li 1 bn tin SYN (bc 2 trong
VD), n chuyn sang trng thi SYN Received.
- Lc ny client gi li bn tin xc nhn ACK (bc 3 trong v d), n chuyn sang trng thi
thit lp kt ni Established.
- Server nhn c bn tin ACK trn ca client, n cng chuyn sang trng thi Established.
- Sau 2 bn tin hnh truyn d liu, trng thi c 2 pha u l Established.
- Mt trong hai pha truyn xong d liu, n y th vai tr hai bn l nh nhau, ta gi s
client truyn xong d liu trc, n s gi bn tin FIN, v chuyn sang trng thi FIN wait 1.
- Pha server nhn c bn tin ny, gi xc nhn ACK, v chuyn sang trng thi Close wait.
- Khi client nhn c xc nhn t server (nhn c bn tin ACK trn) th n chuyn sang
trng thi FIN wait 2.
- n lc ny server vn c th tip tc gi d liu v client vn tip tc nhn (v ch c client
bo l gi xong d liu).
- n khi no server cng gi ht d liu, n s gi i bn tin FIN, cho bit n cng gi
xong d liu v chuyn sang trng thi LAST ACK.
- Khi client nhn c bn tin FIN trn t server, n gi xc nhn (ACK) v chuyn sang trng
thi Time wait, sau ch 1 khong thi gian Timeout v ng kt ni, quay li trng thi
Close.
- Khi server nhn c n cng chuyn t Last ACK sang Close (khng cn i Timeout)
Trn y ch l kch bn thng thng nht. Lu trn cn gii quyt cho cc kch bn khc.

thay i khng kh t. Hm trc mnh ni l nu vit xong giao thc ICMP, cha cn TCP
v UDP, th c th ping c ti board mch ca chng ta. T u n gi chng ta vit
code qu tri lun m cha th np vo chip chy th 1 ci, k cng hi nn. Vy ti y
mnh dng li hng dn b sung mt s hm v vit hm main() trong file ntAVRnet.c
c th bin dch np vo chip Atmega32, sau ta s th ping ti mch xem mch ca ta
hot ng cha nh.
u tin, ta phi vit mt s hm m t u n gi ta vn cha vit: l hm printf s dng
uart xut thng tin ln cng COM trn my tnh v ngt cho timer.
Phn ny s khng gii thch chi tit v khng phi l trng tm chnh, cc bn t tm hiu nh:
Thm vo project cp file uart.c v uart.h
Ni dung file uart.c:
Code:
//---------------------------------------------------------------------------// Writen by NTTam - PTITHCM
//---------------------------------------------------------------------------#include <avr/io.h>
#include <avr/pgmspace.h>
#include <avr/interrupt.h>
#include <stdarg.h>
#include "ntAVRnet.h"
#include "uart.h"
//---------------------------------------------------------------------------char UartRxBuffer[UART_RX_BUFFER_SIZE];
char UartTxBuffer[UART_TX_BUFFER_SIZE];
volatile unsigned char UartTxBufferStart;
volatile unsigned char UartTxBufferLen;
volatile unsigned char UartRxBufferStart;
volatile unsigned char UartRxBufferLen;
static char HexTable[] PROGMEM= "0123456789ABCDEF";
//---------------------------------------------------------------------------void uartInit(unsigned long baudrate)
{
unsigned int bauddiv = ((F_CPU+(baudrate*8L))/(baudrate*16L)-1);//
UBRRL = bauddiv;
#ifdef UBRRH
UBRRH = ((bauddiv>>8) & 0x0F);
// URSEL
7
// UMSEL
6
0:Asynchronuos/1:Synchronous
// UPM1
5
Parity mode: 00:disabled/01:Reserved/10:Even/11:Odd
// UPM0
4
// USBS
3
Stop bit: 0:1 bit/1:2 bit
// UCSZ1
2
Char size:000:5/001:6/010:7/011:8/111:9/others:reserverd
// UCSZ0
1
// UCPOL
0
UCSRC = 0x80 | (1<<UCSZ1) | (1<<UCSZ0);
#endif
UCR =((1 << TXEN) | (1 << RXEN) | (1<< RXCIE) | (1<< TXCIE));//
UartTxBufferStart = 0;
UartTxBufferLen = 0;
UartRxBufferStart = 0;
UartRxBufferLen = 0;
sei();
}
//-------------------------------------------------------------------------------------SIGNAL(SIG_UART_TRANS)
{
if(UartTxBufferLen){
--UartTxBufferLen;
UDR = UartTxBuffer[UartTxBufferStart++];
if (UartTxBufferStart == UART_TX_BUFFER_SIZE)

UartTxBufferStart = 0;
}
}
//-------------------------------------------------------------------------------------SIGNAL(SIG_UART_RECV)
{
unsigned char i;
char status,data;
status = USR;
data = UDR;
if ((status & ((1<<FE) | (1<<PE) | (1<<DOR))) == 0){
if(++UartRxBufferLen == UART_RX_BUFFER_SIZE)
UartRxBufferLen = UART_RX_BUFFER_SIZE;
i = UartRxBufferStart+UartRxBufferLen;
//Vi tri ky tu cuoi cung trong
buffer
if(i > UART_RX_BUFFER_SIZE)
i -= UART_RX_BUFFER_SIZE;
UartRxBuffer[i-1] = data;
}
}
//-------------------------------------------------------------------------------------char uartGetByte(void)
{
//
char c;
if(UartRxBufferLen){
UartRxBufferLen--;
c = UartRxBuffer[UartRxBufferStart++];
if(UartRxBufferStart == UART_RX_BUFFER_SIZE)
UartRxBufferStart = 0;
return(c);
}
return(-1);
}
//-------------------------------------------------------------------------------------void uartSendByte(char c)
{
unsigned char i;
if((USR & (1<<UDRE)) && (UartTxBufferLen == 0)){
//Neu uart dang san sang va
buffer trong
UDR = c;
//Gui luon
}else{
//Neu uart dang ban
while(UartTxBufferLen == UART_TX_BUFFER_SIZE);
//Cho neu buffer dang
day
i = UartTxBufferStart + UartTxBufferLen;
UartTxBufferLen++;
if(i >= UART_TX_BUFFER_SIZE)
i -=UART_TX_BUFFER_SIZE;
UartTxBuffer[i] = c;
//Ghi vao cuoi buffer
}
}
//-------------------------------------------------------------------------------------int printfP(const prog_char *format, ...)
{
// simple printf routine
// define a global HexChars or use line below
//static char HexChars[16] = "0123456789ABCDEF";
char c;
unsigned int u_val, div_val, base;
va_list ap;
va_start(ap, format);
for (;;)
{

while ((c = pgm_read_byte(format++) ) != '%')


{
// Until '%' or '\0'
if (!c)
{
va_end(ap);
return(0);
}
uartSendByte(c);
}

//

switch (c = pgm_read_byte(format++) )
{
case 'c': c = va_arg(ap,int);
default: uartSendByte(c); continue;
case 'd': base = 10; div_val = 10000; goto CONVERSION_LOOP;
case 'x': base = 16; div_val = 0x10;
case 'x': base = 16; div_val = 0x1000;
CONVERSION_LOOP:
u_val = va_arg(ap,int);
if (c == 'd')
{
if (((int)u_val) < 0)
{
u_val = - u_val;
uartSendByte('-');
}
while (div_val > 1 && div_val > u_val) div_val /= 10;
}
do
{
//c =pgm_read_byte(HexTable+(u_val/div_val));
uartSendByte(pgm_read_byte(HexTable+(u_val/div_val)));
u_val %= div_val;
div_val /= base;
} while (div_val);
}
}
va_end(ap);

}
//--------------------------------------------------------------------------------------

Ni dung file uart.h:


Code:
//---------------------------------------------------------------------------// Writen by NTTam - PTITHCM
//---------------------------------------------------------------------------#ifndef UART_H
#define UART_H
#include <avr/pgmspace.h>
//---------------------------------------------------------------------------#define UART_TX_BUFFER_SIZE
8
#define UART_RX_BUFFER_SIZE
8
//-------------------------------------------------------------------------------------#ifndef UART_INTERRUPT_HANDLER
#define UART_INTERRUPT_HANDLER
SIGNAL
#endif
//define for ATmega32 register
#define USR UCSRA
#define UCR UCSRB
#define UBRR UBRRL
#define EICR EICRB

#define USART_RX USART_RXC_vect


#define USART_TX USART_TXC_vect
//-------------------------------------------------------------------------------------void uartInit(unsigned long baudrate);
char uartGetByte();
void uartSendByte(char c);
int printfP(const prog_char *format, ...);
#define printf(format, args...) printfP(PSTR(format), ## args)
//-------------------------------------------------------------------------------------#endif //UART_H

Tip tc hm vo project cp file timer.c v timer.h


Ni dung file timer.c:
Code:
//---------------------------------------------------------------------------// Writen by NTTam - PTITHCM
//---------------------------------------------------------------------------#include <avr/io.h>
#include <avr/interrupt.h>
#include "ntAVRnet.h"
#include "timer.h"
#include "ethernet.h"
#include "arp.h"
//#include "tcp.h"
//---------------------------------------------------------------------------extern volatile unsigned int time_watchdog;
static volatile unsigned long UptimeMs;
static volatile unsigned char Counter10ms;
static volatile unsigned int Counter1s;
//---------------------------------------------------------------------------void timer1Init(void)
{
// initialize timer 1
// set prescaler on timer 1
TCCR1B = (TCCR1B & ~TIMER_PRESCALE_MASK) | TIMER1PRESCALE; // set prescaler
TCNT1H = 0;
// reset TCNT1
TCNT1L = 0;
TIMSK |= (1<<TOIE1);
// enable
TCNT1 overflow
TCNT1 = 0xFFFF - TIMER1_INTERVAL;
}
void timerInit(void)
{
timer1Init();
sei();
}
//! Interrupt handler for tcnt1 overflow interrupt
TIMER_INTERRUPT_HANDLER(SIG_OVERFLOW1)
{
//Tai nap gia tri timer 1
TCNT1 = 0xFFFF - TIMER1_INTERVAL;
//Cap nhat watchdog timer
if((time_watchdog++) > 120){
time_watchdog = 0;
ethInit();
}
Counter1s++;
arpTimer();
//TCPCheckTimeOut();
}

Ni dung file timer.h:

Code:
//---------------------------------------------------------------------------// Writen by NTTam - PTITHCM
//---------------------------------------------------------------------------#ifndef TIMER_H
#define TIMER_H
//---------------------------------------------------------------------------#define TIMER_CLK_STOP
0x00
///< Timer Stopped
#define TIMER_CLK_DIV1
0x01
///< Timer clocked at F_CPU
#define TIMER_CLK_DIV8
0x02
///< Timer clocked at F_CPU/8
#define TIMER_CLK_DIV64
0x03
///< Timer clocked at F_CPU/64
#define TIMER_CLK_DIV256
0x04
///< Timer clocked at F_CPU/256
#define TIMER_CLK_DIV1024
0x05
///< Timer clocked at F_CPU/1024
#define TIMER_CLK_T_FALL
0x06
///< Timer clocked at T falling edge
#define TIMER_CLK_T_RISE
0x07
///< Timer clocked at T rising edge
#define TIMER_PRESCALE_MASK
0x07
///< Timer Prescaler Bit-Mask
#define TIMER1PRESCALE
#ifndef TIMER_INTERRUPT_HANDLER
#define TIMER_INTERRUPT_HANDLER
#endif
void timer1Init(void);
void timerInit(void);

TIMER_CLK_DIV64

///< timer 1 prescaler default

SIGNAL

#endif //TIMER_H

Mc ch chnh ca timer y l ta to ra ngt ( y dng timer 1, cc bn dng timer no


cng c), gi hm kim tra timeout v cp nht watchdog timer.
Thm define vo ntAVRnet.h
Code:
#define TIMER_PRESCALE
#define TIMER1_INTERVAL

1024
(F_CPU/TIMER_PRESCALE)

#define IPDOT(a,b,c,d)
((unsigned long)((unsigned char)a)<<24)+((unsigned long)
((unsigned char)b)<<16)+((unsigned long)((unsigned char)c)<<8)+(unsigned char)d//
((a<<24)|(b<<16)|(c<<8)|(d))
#define IPADDRESS
IPDOT(192,168,1,10)
#define NETMASK
IPDOT(255,255,255,0)
#define GATEWAY
IPDOT(192,168,1,1)
#define
#define
#define
#define
#define
#define

ETHADDR0
ETHADDR1
ETHADDR2
ETHADDR3
ETHADDR4
ETHADDR5

'0'
'F'
'F'
'I'
'C'
'E'

Thm include vo ethernet.c t c th gi cc hm ca giao thc ip v arp:


Code:
#include "arp.h"
#include "ip.h"

Thm include vo file ip.c:


Code:
#include "icmp.h"

#include "uart.h"

V thm thm // vo trc lnh gi hm UDPProcess, TCPProcess trong hm IPProcess (v ta


vn cha vit 2 hm ny ca giao thc UDP v TCP).
M ntAVRnet.c:
Thm hm khi ng cc dch v mng:
Code:
void netInit(unsigned long ipaddress, unsigned long netmask, unsigned long gatewayip)
{
// init network device driver
#ifdef NET_DEBUG
printf("Initializing Network Device\r\n");
#endif
ethInit();
// init ARP
#ifdef NET_DEBUG
printf("Initializing ARP cache\r\n");
#endif
arpInit();
// init addressing
#ifdef NET _DEBUG
printf("Initializing Addressing\r\n");
#endif
ipSetConfig(ipaddress, netmask, gatewayip);
//dhcpInit();
//TCPInit();
//httpInit();
}

Hm xut ra cng serial cc thng tin cu hnh IP:


Code:
//-------------------------------------------------------------------------------------void
PrintIPConfig()
{
printf("MAC Address: ");
ethPrintAddr(&IpMyConfig.ethaddr);
printf("\n\r");
printf("IP Address: ");
ipPrintAddr(IpMyConfig.ip);
printf("\n\r");
printf("Subnet Mask: ");
ipPrintAddr(IpMyConfig.netmask);
printf("\n\r");
printf("Default Gateway: ");
ipPrintAddr(IpMyConfig.gateway);
printf("\n\r");
}

hm ny c th truy xut bin IpMyConfig nm trong module ip.c, ta thm dng khai bo
sau vo u file ntAVRnet.c.
Code:
extern struct ipConfig IpMyConfig;

V vit hm khi ng h thng:


Code:
//-------------------------------------------------------------------------------------void
SystemInit()
{
timerInit();

uartInit(UART_BAUDRATE);
}

V cui cng l vit hm main():


Code:
int
{

main(void)
SystemInit();
printf("\r\nNTTam AVR network testing with enc28j60.\r\n");
printf("Initializing Network Interface and Stack\r\n");
printf("Ethernet chip init\r\n");
IpMyConfig.ethaddr.addr[0] = ETHADDR0;
IpMyConfig.ethaddr.addr[1] = ETHADDR1;
IpMyConfig.ethaddr.addr[2] = ETHADDR2;
IpMyConfig.ethaddr.addr[3] = ETHADDR3;
IpMyConfig.ethaddr.addr[4] = ETHADDR4;
IpMyConfig.ethaddr.addr[5] = ETHADDR5;
IpMyConfig.ip = IPADDRESS;
IpMyConfig.netmask = NETMASK;
IpMyConfig.gateway = GATEWAY;
netInit(IpMyConfig.ip, IpMyConfig.netmask, IpMyConfig.gateway);
PrintIPConfig();
while(1)
{
ethService();
}
return 0;}

Bin dch, np chip v th g lnh ping 192.168.1.10 xem sao.


a ch IP, Subnet v gateway cc bn c th thay i cc define trong file ntAVRnet.h
cho ph hp vi mng nh mnh nh.
gip mi ngi lm mch, mnh post thm file mch in m mnh lm:
AEC32_VER1_1.zip

Hu ht linh kin c th mua ti Trang ch - Thin Minh Electronic Solutions

Danh sch LK v gi tham kho:

Nguyn vn bi rptdnmqs

Thy gii thch dm em ci hm ipchecksum.Em tng check sum l cng tng byte d liu li
thi.Sao m li c ci while l th.
Hehe, bi vy, lc vit code ch ny ti cng tng vy, c ngh l mnh bit ri, t ra l cha
bit g c (hay ni chnh xc hn l bit cha ti). Nguyn nhn l th ny:
- ng l checksum l cng li nhng:
1-Cng tng word (16 bit) ch khng phi tng byte
2-Checksum IP c quy nh l: "b-1 16 bit ca tng b-1 ca tt ca cc t 16 bit trong
header IP".
Nghe hi kh hiu, c th l th ny:
- u tin ta cng cc t 16 bit trong header:
Code:
for (;;) {
if (len < 2)
break;
sum += *((unsigned int *)data);
data+=2;
len -= 2;
}

Nn nh data l bin con tr n kiu char, v vy ta p kiu n sang bin con tr kiu int:
(unsigned int *)data v ly gi tr ti a ch con tr th c s 16 bit: *((unsigned int *)data).
Tip theo ta tng bin con tr thm 2 byte v tr len i 2 byte. Lp n khi no s byte cn li
nh hn 2.
n y, nu s byte l chn, len=0, nu s byte l (chia tng cp 2 byte cn tha li 1 byte)
th len=1. Ta cng nt byte vo (xem n nh l 1 t 2 byte m byte cao bng 0x00):
Code:

if (len)//Tuc la len=1, con thua 1 byte


sum += *(unsigned char *) data;

Nh vy l ta tnh tng ca header xong, nhng nn nh khi cng nh vy trong AVR, kt qu


s l tng b-2 ch khng phitng b-1 nh yu cu.
chuyn tng b-2 sang b-1, ta cn cng phn d vo, chnh v l do ny m ta khai bo
bin sum l bin long, c chiu di 4 byte, hai byte cao ca n cha phn d.
Code:
while ((len = (unsigned int) (sum >> 16)) != 0)
sum = (unsigned int) sum + len;

y ta gn len=(unsigned int) (sum >> 16) chnh l 2 byte cao ca bin 4 byte sum, lc ny
bin len c tn dng nh l 1 bin tm thi, khng c ngha l chiu di na.
Ta em phn d (2 byte cao, c cha trong bin len) cng vi 2 byte thp: (unsigned int)
sum (phi p kiu sum t long sang int nu khng n s cng c 4 byte ca sum).
Vng lp ny cho n khi no 2 byte cao ca sum=0x0000 (ht phn d).
Vy kt qu ta thu c by gi l :"tng b-1 ca tt ca cc t 16 bit trong header IP".
Cui cng ta cn ly b-1 ca kt qu ny, l checksum IP.
Code:
return (unsigned int) sum ^ 0xFFFF;

Phc tp cha. ni l khi vit phn ny ti mt 4h ch sa hm checksum v debug cc


gi IP xem mnh sai ch no. Em thc mc cng khng c g l.
By gi l phn code cho TCP :
Ta li to 2 file source v header :
tcp.c :
Code:
//---------------------------------------------------------------------------// Writen by NTTam - PTITHCM
//---------------------------------------------------------------------------#include "packet.h"
#include "ethernet.h"
#include "ip.h"
#include "uart.h"
#include "tcp.h"

tcp.h :
Code:
//---------------------------------------------------------------------------// Writen by NTTam - PTITHCM
//---------------------------------------------------------------------------#ifndef TCP_H
#define TCP_H
#endif //TCP_H

u tin l m file packet.h, thm m t TCP header vo :


Code:
//-------------------------------------------------------------------------------------//Cau truc TCP header
struct ntTCPHeader

{
unsigned
unsigned
unsigned
unsigned
unsigned
unsigned
unsigned
unsigned
unsigned
unsigned

int
int
long
long
char
char
int
int
int
char

};
#define TCP_HEADER_LEN

srcPort;
desPort;
seqNumber;
ackNumber;
Offset;
Flags;
Window;
Checksum;
UrgentPtr;
optdata[8];
20

nh ngha cc c (flags) trong header TCP: v khi truy xut buffer, ta ch truy xut c tng
byte, sau ta da vo mask ca cc c c nh ngha y truy xut ti c tng ng.
Code:
#define
#define
#define
#define
#define
#define
#define
#define
#define

TCP_NON_FLAG
TCP_FIN_FLAG
TCP_SYN_FLAG
TCP_RST_FLAG
TCP_PSH_FLAG
TCP_ACK_FLAG
TCP_URG_FLAG
TCP_ECE_FLAG
TCP_CWR_FLAG

(0)
(1<<0)
(1<<1)
(1<<2)
(1<<3)
(1<<4)
(1<<5)
(1<<6)
(1<<7)

Tip theo ta quay li tcp.h, nh ngha mt s hng s s dng cho giao thc TCP
u tin l gi tr MSS (Max Segment Size Kch thc on d liu ti a m ta c th nhn).
Ch ny cc bn xem li minh ha ch 2 c th k l hiu ngha gi tr ny lin.
Code:
#define MAX_SEGMENT_SIZE (ETHERNET_BUFFER_SIZE - ETH_HEADER_LEN - IP_HEADER_LEN TCP_HEADER_LEN)

Tip theo l nh ngha cc trng thi trong TCP (xem li phn lu chuyn i trng thi
nh).
Code:
//List the TCP session state
#define TCP_STATE_CLOSED
0
#define TCP_STATE_SYN_SENT
1
#define TCP_STATE_LISTEN
2
#define TCP_STATE_SYN_RECEIVED 3
#define TCP_STATE_ESTABLISHED 4
#define TCP_STATE_FIN_WAIT1
5
#define TCP_STATE_FIN_WAIT2
6
#define TCP_STATE_CLOSING
7
#define TCP_STATE_TIMED_WAIT
8
#define TCP_STATE_CLOSE_WAIT
9
#define TCP_STATE_LAST_ACK
10

nh ngha thi gian timeout cho 1 kt ni TCP: ci ny rt quan trng, c th trong 1 phin
TCP ang kt ni, cha n giai on gii ta, nhng pha bn kia v l do no m ngng
lin lc, nu ch ht Timeout ta phi gii ta kt ni gii phng b nh.
Code:
//60 seconds timeout:
#define TCP_TIMEOUT 60

S kt ni ng thi ti a cho php:


Code:
//maximum connection count
#define TCP_MAX_SESSION 8

Tip theo ta khai bo 1 kiu struct lu thng tin v 1 kt ni:


Code:
//-------------------------------------------------------------------------------------struct tcpSession{
unsigned int desPort;
//Port on the remote host
unsigned int srcPort;
//Port on the local host
unsigned long desIP;
//IP address of the remote host
unsigned long seqNumber; //Sequence number
unsigned long ackNumber; //Acknowlegement number
unsigned char sesState; //Current state of TCP session
unsigned int srcWin;
unsigned int desWin;
unsigned long lastRxAck; //Last Received Ack
unsigned char nextAck;
unsigned char timeOut;
//Session time out
void(*appDataIn)(unsigned char* dataBuffer,unsigned int dataLen,struct tcpSession
*pSession);
unsigned char appID;
//Upper layer application ID
unsigned char appState; //Upper layer application state
};

By gi chuyn sang tcp.c:


Khai bo 1 bng TCP session, trong mi dng l 1 struct tcpSession lu thng tin v 1 kt
ni:
Code:
//-------------------------------------------------------------------------------------struct tcpSession tcpSessionTable[TCP_MAX_SESSION];

Vit hm khi to s tun t (sequence number) cho 1 kt ni TCP. Cc bn xem li phn minh
ha (2 c th k). Mi pha s t chn 1 s tun t bt u. Trn my tnh, con s ny
thng c ly theo thi gian. y cho n gin, ta ch chn i 1 s m thi.
Code:
//-------------------------------------------------------------------------------------//Ham khoi tao so tuan tu cho mot phien TCP
// Hien tai su dung gia tri 1234 (may tinh thuong dung gia tri thoi gian hien tai)
unsigned long TCPInitSequenceNumber()
{
return(1234);
}

Tip theo l hm ng 1 phin TCP:


Code:
//-------------------------------------------------------------------------------------//Ham dong mot phien TCP
void TCPCloseSession(unsigned char socketnum)
{
tcpSessionTable[socketnum].sesState = TCP_STATE_CLOSED;
#ifdef TCP_DEBUG
printf("Close TCP session %d\r\n",socketnum);
#endif
}

Vit hm khi to cc bin cho giao thc TCP:


Code:
//-------------------------------------------------------------------------------------//Khoi dong cac gia tri trong bang TCP session
void TCPInit()
{
unsigned char i = 0;
for(i=0; i<TCP_MAX_SESSION; i++){
TCPCloseSession(i);
}
}

Code:
Hm tm kim 1 phin TCP ang ri trong bng TCP session table ( m kt ni mi)
//-------------------------------------------------------------------------------------//Tim mot session TCP dang roi
unsigned char TCPGetFreeSession(){
unsigned char i;
for(i=0; i<TCP_MAX_SESSION; i++){
if (tcpSessionTable[i].sesState == TCP_STATE_CLOSED)
return i;
}
//no free closed socket fount! -> kick an TIMED_WAIT socket
for(i=0; i<TCP_MAX_SESSION; i++){
if (tcpSessionTable[i].sesState == TCP_STATE_TIMED_WAIT){
TCPCloseSession(i);
return i;
}
}
//no more free sockets ... return invalid val
return(TCP_MAX_SESSION);
}

Vit hm khi to mt kt ni mi ( ch server):


Code:
//-------------------------------------------------------------------------------------//Ham khoi tao mot session TCP o che do server de cho ket noi
void
TCPCreateSession(unsigned int sourcePort, prog_void* appService)
{
unsigned char i;
i = TCPGetFreeSession();
if(i >= TCP_MAX_SESSION)
i = 0; //force session 0
tcpSessionTable[i].srcPort = sourcePort;
tcpSessionTable[i].sesState = TCP_STATE_LISTEN;
//Current state of
TCP session
tcpSessionTable[i].srcWin = 8192;//NETSTACK_BUFFERSIZE - ETH_HEADER_LEN IP_HEADER_LEN - TCP_HEADER_LEN - 16;
tcpSessionTable[i].desWin = tcpSessionTable[i].srcWin;
tcpSessionTable[i].timeOut = TCP_TIMEOUT;
//Session time out
tcpSessionTable[i].appDataIn = appService;
#ifdef TCP_DEBUG
printf("TCP session created: %d\r\n", i);
#endif
}

Hm kim tra Timeout ca cc phin TCP ang kt ni


Code:

//-------------------------------------------------------------------------------------//Duoc goi moi giay de kiem tra Time out cho cac phien TCP,
// giai phong cac phine TCP bi treo
void TCPCheckTimeOut(){
unsigned char i;
for(i=0; i<TCP_MAX_SESSION; i++){
//decrement ttl:
if ((tcpSessionTable[i].sesState != TCP_STATE_CLOSED) &&
(tcpSessionTable[i].sesState != TCP_STATE_LISTEN)){
if(tcpSessionTable[i].timeOut)
tcpSessionTable[i].timeOut--;
//if socket TTL count is zero, close this socket!
if (tcpSessionTable[i].timeOut == 0){
TCPCloseSession(i);
}
}
}
}

Hm tnh checksum cho gi TCP


Code:
//-------------------------------------------------------------------------------------//Tinh checksum cho goi TCP
unsigned int checksum(unsigned char *buffer, unsigned int len, unsigned long csum32)
{
unsigned int res16 = 0x0000;
unsigned char data_hi;
unsigned char data_lo;
while(len > 1){
data_hi = *buffer++;
data_lo = *buffer++;
res16 = (((unsigned int)data_hi << 8) + data_lo);
csum32 = csum32 + res16;
len -=2;
}
if(len > 0){
data_hi = *buffer;
res16
= (unsigned int)data_hi<<8;
csum32 = csum32 + res16;
}
while(csum32>>16)
csum32 = (csum32 & 0xFFFF)+ (csum32 >> 16);
//csum32 = ((csum32 & 0x0000FFFF)+ ((csum32 & 0xFFFF0000) >> 16));
res16 =~(csum32 & 0x0000FFFF);
return (res16);
}

Tip theo l hai hm chnh ca giao thc:


Hm gi 1 on d liu i bng giao thc TCP:
Code:
//-------------------------------------------------------------------------------------//Gui di mot goi TCP
void TCPPackedSend(struct tcpSession *pSession, unsigned char Flags, unsigned int len,
unsigned char *dataBuffer)
{
unsigned int tmp;
unsigned long checksum32;
//Make pointer to TCP header

struct ntTCPHeader* tcpHeader;


struct ntIPHeader* ipHeader;
//Neu dang syn thi them option ve MSS
if(Flags & TCP_SYN_FLAG){
//Option data
dataBuffer[0] = 0x02;
dataBuffer[1] = 0x04;
dataBuffer[2] = (MAX_SEGMENT_SIZE >> 8) & 0xff;
dataBuffer[3] = MAX_SEGMENT_SIZE & 0xff;
dataBuffer[4] = 0x01;
dataBuffer[5] = 0x03;
dataBuffer[6] = 0x03;
dataBuffer[7] = 0x00;
//Move data pointer to make room for TCP header
}
dataBuffer -= TCP_HEADER_LEN;
tcpHeader = (struct ntTCPHeader*)dataBuffer;
//Fill UDP header
tcpHeader->srcPort = HTONS(pSession->srcPort);
tcpHeader->desPort = HTONS(pSession->desPort);
tcpHeader->seqNumber = HTONL(pSession->seqNumber);
pSession->seqNumber = pSession->seqNumber + len;
if(Flags & (TCP_FIN_FLAG|TCP_SYN_FLAG))
(pSession->seqNumber)++;
tcpHeader->ackNumber = HTONL(pSession->ackNumber);
if(Flags & TCP_SYN_FLAG){
tcpHeader->Offset = (0x07<<4);
len += (TCP_HEADER_LEN + 8);
}else{
tcpHeader->Offset = (0x05<<4);
len += TCP_HEADER_LEN;
}
tcpHeader->Flags = Flags;
tcpHeader->Window = HTONS(pSession->srcWin);//((NETSTACK_BUFFERSIZE-20-14));
tcpHeader->Checksum = 0;
tcpHeader->UrgentPtr = 0x0000;
//Generate checksum
ipHeader = (struct ntIPHeader*)(dataBuffer-IP_HEADER_LEN);
ipHeader->srcIPAddr = HTONL(ipGetConfig()->ip);
ipHeader->desIPAddr = HTONL(pSession->desIP);
ipHeader->Checksum = HTONS(len);
ipHeader->TTL = 0x00;
ipHeader->Protocol = IP_PROTO_TCP;
checksum32 = 0;
tmp = len + 12;
tmp = checksum (((unsigned char *)ipHeader+8), tmp, checksum32);
tcpHeader->Checksum = HTONS(tmp);
ipSend(pSession->desIP, IP_PROTO_TCP, len, (unsigned char *)tcpHeader);
}

Hm x l khi nhn c 1 gi TCP


Code:
//-------------------------------------------------------------------------------------//Ham xu ly goi TCP nhan duoc, duoc goi boi giao thuc IP (IPProcess)
void TCPProcess(unsigned char *buffer, unsigned int len)
//Ham xu ly cho giao thuc TCP
// Duoc thuc thi khi nhan duoc mot goi TCP (goi boi netstackIPProcess)
// buffer: co tro den dau goi IP (bat dau IP Header)
// len
: chieu dai buffer
{
unsigned char i,ipHeaderLen,tcpHeaderLen;
unsigned int dataLen;
unsigned long tmp;

struct ntIPHeader* ipHeader;


struct ntTCPHeader* tcpHeader;
unsigned char *tcpData;
//Khoi tao cac co tro den Header IP va TCP
ipHeader = (struct ntIPHeader*)(buffer);
ipHeaderLen = ((ipHeader->verHdrLen) & 0x0F) << 2;
//
tcpHeader = (struct ntTCPHeader*)(buffer+ipHeaderLen);
tcpHeaderLen = ((tcpHeader->Offset) & 0xF0) >> 2;
//
tcpData = (buffer+ipHeaderLen+tcpHeaderLen);
dataLen = HTONS(ipHeader->Len) - (ipHeaderLen + tcpHeaderLen);
//Tim kiem mot phien TCP co san cho goi nay
for(i = 0; i < TCP_MAX_SESSION; i++){
//Check session table
if(tcpSessionTable[i].sesState != TCP_STATE_CLOSED){
//If
not closed session
if(tcpSessionTable[i].srcPort == HTONS((tcpHeader->desPort))){
//If matched local port
if(tcpSessionTable[i].desPort == HTONS((tcpHeader>srcPort))&&(tcpSessionTable[i].desIP == HTONL((ipHeader->srcIPAddr)))){
break; //Thoat khoi vong lap for, luc nay gia
tri cua i chinh la chi so cua phien TCP tuong ung
}
}
}
}
if(i == TCP_MAX_SESSION){ //Neu khong co 1 phien TCP dang ton tai cho goi nay
//Tim 1 phien dang o trang thai LISTEN (doi ket noi) cho local port nay
for(i=0; i < TCP_MAX_SESSION; i++){
if(tcpSessionTable[i].sesState == TCP_STATE_LISTEN){
if(tcpSessionTable[i].srcPort == HTONS((tcpHeader>desPort))){
//If matched local port
//Cap nhat remote port va remote IP
tcpSessionTable[i].desPort = HTONS((tcpHeader>srcPort));
tcpSessionTable[i].desIP = HTONL((ipHeader>srcIPAddr));
//Dong thoi tao ra 1 session moi de cho ket noi
khac den local port nay
TCPCreateSession(tcpSessionTable[i].srcPort,tcpSessionTable[i].appDataIn);
break;
}
}
}
}
if(i == TCP_MAX_SESSION){
#ifdef TCP_DEBUG
printf("No TCP session found\r\n");
#endif
return; //Neu khong co phien TCP nao danh cho goi nay thi thoat ra
}
#ifdef TCP_DEBUG
printf("TCP session found: %d\r\n",i);
#endif
//Bat dau xu ly giao thuc
tcpSessionTable[i].timeOut = TCP_TIMEOUT; //Reset lai gia tri Time out
//Truong hop nhan duoc yeu cau reset lai ket noi
if ((tcpHeader->Flags) & TCP_RST_FLAG){
//Chap nhan dong ket noi
TCPCloseSession(i);
return;
}
//Kiem tra trang thai hien tai cua phien TCP

switch (tcpSessionTable[i].sesState){
//Neu la trang thai doi ket noi: TCP_STATE_LISTEN
case(TCP_STATE_LISTEN):
//Chi xu ly neu co SYN duoc set (yeu cau thiet lap ket noi)
if ((tcpHeader->Flags) == TCP_SYN_FLAG){
//Chuyen sang trang thai ke tiep la
TCP_STATE_SYN_RECEIVED
tcpSessionTable[i].sesState = TCP_STATE_SYN_RECEIVED;
//Khoi tao gia tri sequence
tcpSessionTable[i].seqNumber =
HTONL(TCPInitSequenceNumber());
//Ack chinh la so tuan tu nhan duoc cong 1
tcpSessionTable[i].ackNumber = HTONL((tcpHeader>seqNumber))+1;
tcpSessionTable[i].desWin = HTONS((tcpHeader->Window));
//Goi tra xac nhan va co SYN (SYN & ACK)
TCPPackedSend(&tcpSessionTable[i],(TCP_SYN_FLAG|
TCP_ACK_FLAG),0,tcpData);
//Tang so tuan tu len 1
//tcpSessionTable[i].seqNumber++;
#ifdef TCP_DEBUG
printf("SYN received\r\n");
#endif
}
break;
//Neu la trang thai TCP_STATE_SYN_RECEIVED
case(TCP_STATE_SYN_RECEIVED):
//Neu co co ACK (cho ban tin SYN & ACK truoc do)
if ((tcpHeader->Flags) == TCP_ACK_FLAG){
//Kiem tra ack trong goi tin den, neu dung thi thiet
lap ket noi hoan tat
if((tcpSessionTable[i].seqNumber) == HTONL((tcpHeader>ackNumber))){
tcpSessionTable[i].sesState =
TCP_STATE_ESTABLISHED;
//Goi tiep theo gui di se co co ACK
tcpSessionTable[i].nextAck = 1;
#ifdef TCP_DEBUG
printf("Connection established\r\n");
#endif
}
}else{ //Neu khong dung ACK
//Khong lam gi ca, goi tin do khong hop le
//TCPCloseSession(i);
}
break;
//Truong hop ket noi da duoc thiet lap
case(TCP_STATE_ESTABLISHED):
//Neu nhan duoc yeu cau ket thuc ket noi tu client
if ((tcpHeader->Flags) & TCP_FIN_FLAG){
//Chuyen sang trang thai ke tiep la trang thai cho ACK
cuoi
//Dung ra o day phai chuyen sang trang thai
TCP_STATE_CLOSE_WAIT nhung khong can thiet
// vi o day ta co the dong ket noi ngay ma khong can
cho gui xong du lieu
tcpSessionTable[i].sesState = TCP_STATE_LAST_ACK;
//Cap nhat ack
tcpSessionTable[i].ackNumber = HTONL((tcpHeader>seqNumber)) + dataLen;
tcpSessionTable[i].ackNumber++;
//Tang 1 cho co FIN
//Gui xac nhan ACK cho yeu cau dong ket noi dong thoi
thong bao san sang dong ket noi

TCPPackedSend(&tcpSessionTable[i],TCP_ACK_FLAG,0,tcpData);
TCPPackedSend(&tcpSessionTable[i],(TCP_FIN_FLAG|
TCP_ACK_FLAG),0,tcpData);
//Dang le truyen o trang thai CLOSE_WAIT nhung ta thuc
hien o day luon
TCPCloseSession(i);
//Neu khong (dang truyen du lieu)
}else{
//Kiem tra ACK tu remote host
if((tcpHeader->Flags) & TCP_ACK_FLAG){
//Neu co co
ACK thi kiem tra gia tri ACK
tcpSessionTable[i].lastRxAck =
HTONL((tcpHeader->ackNumber));
if ((tcpSessionTable[i].seqNumber) ==
HTONL((tcpHeader->ackNumber))){
//Dung ACK
#ifdef TCP_DEBUG
printf("Got ACK\r\n");
#endif
}else{ //Phia ben kia khong nhan duoc du
thong tin
//Sua loi o day
//Process error correction here
//Not finish yet, temporary just
ignore it and continue with next data
//Chua thuc hien
tcpSessionTable[i].seqNumber =
HTONL((tcpHeader->ackNumber));
#ifdef TCP_DEBUG
printf("Miss ACK:got %d\r\nExpected:
%d\n\r",HTONL((tcpHeader->ackNumber)),tcpSessionTable[i].seqNumber+1);
#endif
}
}
//--Ket thuc kiem tra ACK
//Kiem tra sequence number
tmp = HTONL((tcpHeader->seqNumber));
//Neu khong dung goi dang cho nhan
if (tmp != tcpSessionTable[i].ackNumber){
//there was an error, check what to do next:
#ifdef TCP_DEBUG
printf("Incorrect seq, got:%d,expexted:
%d\r\n",tmp,tcpSessionTable[i].ackNumber);
#endif
if (tmp < tcpSessionTable[i].ackNumber){
//Neu dang doi du lieu bat dau tu byte
thu n nhung ta nhan duoc doan du lieu bat dau tu (n-k)
//Tinh phan du lieu thua (k = n - (nk))
tmp = (tcpSessionTable[i].ackNumber tmp);
//Neu doan du lieu thua it hon du lieu
nhan duoc
if(tmp < dataLen){
//Bo di phan du lieu thua,
nhan phan con lai
tcpData += tmp;
dataLen = dataLen - tmp;
}else{ //Neu tat ca du lieu nhan duoc
deu thua
//Gui lai ACK, bo goi vua nhan
duoc
dataLen = 0;

TCPPackedSend(&tcpSessionTable[i],(TCP_ACK_FLAG),0,tcpData);
return;
}
//Neu seq > ack (tuc la co 1 doan du lieu bi
mat)
}else{ //tmp > tcp....
//Yeu cau gui lai
TCPPackedSend(&tcpSessionTable[i],
(TCP_ACK_FLAG),0,tcpData);
return;
}
}
//Neu thuc thi den day nghia la sequence number == ack
number (chinh xac)
//--Ket thuc kiem tra so tuan tu
//Kiem tra chieu dai buffer de chac chan la chieu dai
du lieu nhan duoc khong qua buffer
//
if (tcpData > (buffer + ETHERNET_BUFFER_SIZE))
tcpData = (buffer + ETHERNET_BUFFER_SIZE);
if ((tcpData + dataLen) > buffer +
ETHERNET_BUFFER_SIZE){
dataLen = (buffer + ETHERNET_BUFFER_SIZE) tcpData;
}
//
//Cap nhat ack cho lan nhan ke tiep
tcpSessionTable[i].ackNumber =
tcpSessionTable[i].ackNumber + dataLen;
#ifdef TCP_DEBUG
printf("Data length (%d), buffer size(%d)\n\r",dataLen,
(buffer + ETHERNET_BUFFER_SIZE - tcpData));
printf("Ack Number
(%d)\n\r",tcpSessionTable[i].ackNumber);
#endif
//Goi tiep theo gui di se co co ACK
tcpSessionTable[i].nextAck = 1;
//Goi ham xu ly lop ung dung
if(dataLen != 0){
(tcpSessionTable[i].appDataIn)(tcpData,
dataLen,&tcpSessionTable[i]);
}
}
//--Ket thuc xu ly truong hop dang truyen du lieu
break;
//Neu la trang thai doi LAST_ACK (2 phia deu san sang dong ket noi, dang
doi xac nhan ack cuoi cung)
case(TCP_STATE_LAST_ACK):
//socket is closed
tmp = HTONL((tcpHeader->seqNumber));
//Kiem tra ACK, neu dung ACK
if (tmp == tcpSessionTable[i].seqNumber + 1){
TCPCloseSession(i);
}else{
//Gui lai co FIN & ACK
TCPPackedSend(&tcpSessionTable[i], (TCP_FIN_FLAG|
TCP_ACK_FLAG), 0, tcpData);
}
break;
//Truong hop ngat ket noi thu dong, da nhan co FIN tu remote host va xac
nhan
case(TCP_STATE_CLOSE_WAIT):

//Truong hop nay se khong xay ra vi o tren ta chuyen truc tiep


// sang LAST_ACK khi nhan duoc yeu cau dong ket noi
tcpSessionTable[i].sesState = TCP_STATE_LAST_ACK;
if(dataLen){
tcpSessionTable[i].ackNumber = HTONL((tcpHeader>seqNumber)) + dataLen;
}else{

//Neu dataLen == 0 thi cung tang so tuan tu len 1


tcpSessionTable[i].ackNumber = HTONL((tcpHeader-

>seqNumber))+1;
}
//tcpSessionTable[i].seqNumber = HTONL((tcpHeader->ackNumber));
TCPPackedSend(&tcpSessionTable[i], (TCP_FIN_FLAG|TCP_ACK_FLAG),
0, tcpData);
break;
//Truong hop dang o trang thai FIN WAIT 1 (da truyen du lieu xong,
// san sang dong ket noi va da gui di co FIN va dang cho ACK)
case(TCP_STATE_FIN_WAIT1):
//if we receive FIN
tcpSessionTable[i].ackNumber = HTONL((tcpHeader->seqNumber))+1;
if (tcpHeader->Flags == TCP_FIN_FLAG){
//Neu chi nhan duoc
co FIN
//Chuyen sang trang thai CLOSING va gui ACK
tcpSessionTable[i].sesState = TCP_STATE_CLOSING;
TCPPackedSend(&tcpSessionTable[i], (TCP_ACK_FLAG), 0,
tcpData);
//tcpSessionTable[i].seqNumber++;
#ifdef TCP_DEBUG
printf("Closing\n\r");
#endif
}else if(tcpHeader->Flags == (TCP_FIN_FLAG | TCP_ACK_FLAG)){
//Neu nhan dong thoi FIN va ACK
//Chuyen sang trang thai TIME_WAIT va gui ACK
// nhung o day do chua co timer nen ta chuyen luon
sang dong ket noi
if (HTONL((tcpHeader->ackNumber)) ==
tcpSessionTable[i].seqNumber){
//TCPPackedSend(&tcpSessionTable[i],
(TCP_ACK_FLAG), 0, tcpData);
TCPCloseSession(i);
#ifdef TCP_DEBUG
printf("End\n\r");
#endif
}else{ //Neu khong dung ack cho thong bao FIN
//Chuyen sang cho co ACK cuoi cung
tcpSessionTable[i].sesState =
TCP_STATE_LAST_ACK;
#ifdef TCP_DEBUG
printf("Last ack\n\r");
#endif
}
//Gui xac nhan cho co FIN
TCPPackedSend(&tcpSessionTable[i], (TCP_ACK_FLAG), 0,
tcpData);
//tcpSessionTable[i].seqNumber++;
}else if(tcpHeader->Flags == TCP_ACK_FLAG){
//Neu chi
nhan duoc ACK
//Chuyen sang trang thai FIN WAIT2
tcpSessionTable[i].sesState = TCP_STATE_FIN_WAIT2;
#ifdef TCP_DEBUG
printf("Fin wait 2\n\r");
#endif
}
break;
//Neu dang o trang thai FIN WAIT 2 (san sang dong ket noi va gui co FIN,

// phia ben kia da xac nhan nhung van chua san sang dong ket noi
case(TCP_STATE_FIN_WAIT2):
//Neu nhan duoc co FIN
if (tcpHeader->Flags & TCP_FIN_FLAG){
if(dataLen){
tcpSessionTable[i].ackNumber =
HTONL((tcpHeader->seqNumber))+dataLen;
}else{
tcpSessionTable[i].ackNumber =
HTONL((tcpHeader->seqNumber))+1;
}
//FIN -> goto TIMED WAIT
tcpSessionTable[i].sesState = TCP_STATE_TIMED_WAIT;
TCPPackedSend(&tcpSessionTable[i], (TCP_ACK_FLAG), 0,
tcpData);
//Chua co timer thi dong ket noi o day luon
TCPCloseSession(i);
#ifdef TCP_DEBUG
printf("End\n\r");
#endif
}
break;
case(TCP_STATE_TIMED_WAIT):
break;
case(TCP_STATE_CLOSING):
tcpSessionTable[i].sesState = TCP_STATE_TIMED_WAIT;
break;
default:
TCPCloseSession(i);
}
//we must set timed wait TTL here because timed wait is not packet triggered
if (tcpSessionTable[i].sesState == TCP_STATE_TIMED_WAIT){
tcpSessionTable[i].timeOut = 5; //5 seconds timeout
}
return;
}
//--------------------------------------------------------------------------------------

Hai hm ny khip qu, nhn v thy oi ri, t t gii thch, khng hiu sao hi xa mnh li
vit phc tp nh vy.
Hay l mi ngi c t t nghin cu, ch no khng hiu th c hi

. Gi ngh ti vit gii

thch cho code thy nn qu. Vit gii thch cho code c khi cn kh hn vit code

Giao thc UDP:


Tip theo, ta chuyn sang giao thc UDP, trong 3 giao thc lp ny (TCP, UDP v ICMP) th
UDP l giao thc n gin nht, d vit nht.
Trong chng giao thc IP, nhim v ca UDP l khi nhn 1 segment d liu t ng dng gi
xung, n s gi i ngay n a ch IP v port c yu cu m khng cn nh s th t, bt
tay thit lp kt ni hay thm ch khng quan tm n vic d liu c n c ch hay
khng.
Header ca giao thc UDP rt on gin: ch gm c 4 trng: port ngun, port ch, chiu di
gi tin v checksum.

Trong thc t, UDP c s dng gi i cc d liu m yu cu v tr nh quan trng


hn yu cu v tin cy. V d nh d liu ca cc video stream, audio stream, cc bo hiu
nhanh, hay n gin l tng tc trong cc game online.
Vy ta m file packet.h thm khai bo header UDP vo:
Code:
//-------------------------------------------------------------------------------------//Cau truc UDP header
struct ntUDPHeader
{
unsigned int
srcPort;
unsigned int
desPort;
unsigned int
Len;
unsigned int
Checksum;
};
#define UDP_HEADER_LEN
8

Sau to file source v header tng ng:


udp.c
Code:
//---------------------------------------------------------------------------// Writen by NTTam - PTITHCM
//---------------------------------------------------------------------------#include "packet.h"
#include "ip.h"
#include "uart.h"

udp.h
Code:
//---------------------------------------------------------------------------// Writen by NTTam - PTITHCM
//---------------------------------------------------------------------------#ifndef
UDP_H
#define UDP_H
//---------------------------------------------------------------------------#endif

//UDP_H

Ta ch vit 2 hm cho giao thc UDP:


Hm gi gi tin bng UDP:
Code:
//---------------------------------------------------------------------------//Ham gui di mot goi UDP
void udpSend(unsigned long dstIp, unsigned int dstPort, unsigned int len, unsigned char*
udpData)
{
struct ntUDPHeader* udpHeader;
udpHeader = (struct ntUDPHeader*)(udpData - UDP_HEADER_LEN);
len += UDP_HEADER_LEN;
udpHeader->desPort = HTONS(dstPort);
udpHeader->srcPort = HTONS(dstPort);
udpHeader->Len = HTONS(len);
udpHeader->Checksum = 0;
ipSend(dstIp, IP_PROTO_UDP, len, (unsigned char*)udpHeader);
}

Hm x l gi tin nhn c:
Code:

//-------------------------------------------------------------------------------------//Ham xu ly goi UDP nhan duoc, duoc goi boi ham xu ly goi IP (IPProcess)
// Hien chua co ung dung chay UDP nen ham nay trong
void UDPProcess(unsigned int len, struct ntIPHeader* packet)
{
dhcpIn((len - IP_HEADER_LEN - UDP_HEADER_LEN), (struct netDhcpHeader*)
((char*)packet - IP_HEADER_LEN - UDP_HEADER_LEN));
#ifdef NET_DEBUG
printf("NetStack UDP/IP Rx Dummy Handler\r\n");
#endif
}

V trong project ny, chng ta ch s dng UDP cho 1 ng dng duy nht l DHCP nn y ta
ch gi hm dhcpIn x l. Hm ny ta vn cha vit nh. Nu ta cn dng UDP cho cc giao
thc khc th phc tp hn 1 t, tuy nhin vn n gin hn nhiu so vi TCP.
Tip theo s l DHCP v HTTP, xong ci ny l cc bn c th truy cp web trn mch c ri
(nu c mch

).

built xong code n phn Ping c. Trong qu trnh lm theo anh Tm c vi im anh
Tm ni cha r lm nn hm nay Huy port ln phn code mi lm xong v bin dch OK.
Anh Tm c nhm mt ch nh sau :
Trong hm ny ta c s dng nh ngha vector ngt (ISR), do ta cn include file tng ng
vo. Thm dng ny vo u file "ehternet.c"
Code:
#include <avr/interrupt.h>
Trong hm ny, ta s dng 2 bin ton cc l eth_got_frame v time_watchdog, hai bin ny
cn c khai bo trong file enc28j60.c (nn du file) thay bng ethernet.c
Code:
unsigned char eth_got_frame = 0;
volatile unsigned int time_watchdog;
V ntAVRnet.c cn include nh th ny
<
#include <avr/io.h>
#include "ntAVRnet.h"
#include "ip.h"
extern struct ipConfig IpMyConfig;
>
C g sai anh Tm chnh dm nha. Ti nay v np vo mch ri Ping thi. keke
AVRnet NTT.zip
Gii thch cho 2 hm chnh trong giao thc TCP:
Hm TCPPackedSend:
Code:
void TCPPackedSend(struct tcpSession *pSession, unsigned char Flags, unsigned int len,
unsigned char *dataBuffer)

Trong ny:
- pSession l con tr, tr n struct tcpSession trong bng TCP Session Table tng ng vi
phin kt ni TCP m ta mun gi gi tin i (trong phn lp trnh giao thc TCP ny, ta h tr
vic AVR ng thi theo di v truyn data vi nhiu kt ni (nhiu client) cng lc).
- Flags l cc c tng ng m ta mun set trong header TCP
- len: chiu di buffer d liu ng dng.
- dataBuffer: buffer cha d liu ng dng.

Cu trc frame d liu m ENC28J60 s gi i nh sau:

Lc ny, dataBuffer ang tr n phn Application Data trong frame trn, bin len ang l
chiu di phn data ny.
Khai bo cc bin s dng trong hm:
Code:
unsigned int tmp;
unsigned long checksum32;

Lc ny, trn buffer (dataBuffer) c d liu ng dng (phn Application Data), nhim v ca
giao thc TCP l phi xy dng header TCP cho frame d liu ny.
Tip theo, ta khai bo 2 con tr, tr n vng IP Header v TCP Header (mi khai bo, cha
gn a ch):
Code:
struct ntTCPHeader* tcpHeader;
struct ntIPHeader* ipHeader;

Nu l ang trong giai on thit lp kt ni (c SYN c set) th TCP Header s c thm


trng Option, cha gi tr MSS (Max Segment Size), ta ghi lun vo vng buffer dnh cho
Application Data, v khi SYN th vng ny khng c (cc bn tin thit lp kt ni khng cha d
liu ng dng).
Code:
if(Flags & TCP_SYN_FLAG){
//Option data
dataBuffer[0] = 0x02;
dataBuffer[1] = 0x04;
dataBuffer[2] = (MAX_SEGMENT_SIZE >> 8) & 0xff;
dataBuffer[3] = MAX_SEGMENT_SIZE & 0xff;
dataBuffer[4] = 0x01;
dataBuffer[5] = 0x03;
dataBuffer[6] = 0x03;
dataBuffer[7] = 0x00;
}

By gi ta dch lui con tr dataBuffer 1 on bng chiu di TCP Header v tr tcpHeader n


phn u on ny.
Code:
dataBuffer -= TCP_HEADER_LEN;
tcpHeader = (struct ntTCPHeader*)dataBuffer;

in cc trng cho TCP Header:


- Source port v Des port ly t thng tin v session tng ng:
Code:
tcpHeader->srcPort = HTONS(pSession->srcPort);
tcpHeader->desPort = HTONS(pSession->desPort);

- S tun t cng vy:

Code:
tcpHeader->seqNumber = HTONL(pSession->seqNumber);

Sau ta phi tng s tun t ln ty theo chiu di d liu:


Code:
pSession->seqNumber = pSession->seqNumber + len;

Lu (ch ny lc vit code mnh b sai, debug mt c bui ti): tuy cc bn tin SYN v
FIN khng cha d liu, n vn c xem l c chiu di d liu 1 byte, phi tng s tun t
ln 1 i vi cc bn tin ny:
Code:
if(Flags & (TCP_FIN_FLAG|TCP_SYN_FLAG))
(pSession->seqNumber)++;

S ACK:
Code:
tcpHeader->ackNumber = HTONL(pSession->ackNumber);

Nu c c SYN, nh ni trn Header TCP s c trng Option chiu di 8 byte, do ta phi


ghi gi tr tng ng cho trng Offset, v tng bin len ln tng ng:
Code:
if(Flags & TCP_SYN_FLAG){
tcpHeader->Offset = (0x07<<4);
len += (TCP_HEADER_LEN + 8);

Nu khng, chiu di TCP Header l mc nh ( nh ngha TCP_HEADER_LEN)


Code:
}else{
tcpHeader->Offset = (0x05<<4);
len += TCP_HEADER_LEN;
}

Ghi gi tr cc c
Code:
tcpHeader->Flags = Flags;

Gi tr trng Window
Code:
tcpHeader->Window = HTONS(pSession->srcWin);//((NETSTACK_BUFFERSIZE-20-14));

Tm thi gn checksum = 0 (ta s tnh TCP checksum sau)


Code:
tcpHeader->Checksum = 0;

Con tr khn khng s dng:


Code:
tcpHeader->UrgentPtr = 0x0000;

Tr n bin con tr ipHeader n vng IP Header trn buffer:


Code:
ipHeader = (struct ntIPHeader*)(dataBuffer-IP_HEADER_LEN);

Gn tm thi 1 s gi tr cn thit cho IP Header tnh checksum:


Code:
ipHeader->srcIPAddr = HTONL(ipGetConfig()->ip);
ipHeader->desIPAddr = HTONL(pSession->desIP);
ipHeader->Checksum = HTONS(len);
ipHeader->TTL = 0x00;
ipHeader->Protocol = IP_PROTO_TCP;

y cc bn cn tm hiu thm cch tnh checksum TCP, n khng ch tnh checksum phn
TCP Header v d liu m cn tnh thm 1 s trng ca IP trong 1 header IP gi, do ta
phi gn tm cc trng ny ln buffer th mi tnh c TCP checksum, cn tht ra Header IP
xung giao thc IP s c xy dng li (hm ipSend).
Tnh checksum v ghi vo trng checksum ca Header TCP
Code:
checksum32 = 0;
tmp = len + 12;
tmp = checksum (((unsigned char *)ipHeader+8), tmp, checksum32);
tcpHeader->Checksum = HTONS(tmp);

Gi hm ipSend yu cu giao thc IP gi gi tin i.


Code:
ipSend(pSession->desIP, IP_PROTO_TCP, len, (unsigned char *)tcpHeader);

Hm TCPProcess:
Hm ny di qu nn ch gii thch cu trc hm cho cc bn d c thi:
Khai bo cc bin s dng:
Code:
unsigned char i,ipHeaderLen,tcpHeaderLen;
unsigned int dataLen;
unsigned long tmp;
struct ntIPHeader* ipHeader;
struct ntTCPHeader* tcpHeader;
unsigned char *tcpData;

Tr cc bin con tr header IP v TCP n vng header tng ng. Lc ny trn buffer c
y frame d liu c t ENC28J60.
Code:
//Khoi tao cac co tro den Header IP va TCP
ipHeader = (struct ntIPHeader*)(buffer);
ipHeaderLen = ((ipHeader->verHdrLen) & 0x0F) << 2;
//
tcpHeader = (struct ntTCPHeader*)(buffer+ipHeaderLen);
tcpHeaderLen = ((tcpHeader->Offset) & 0xF0) >> 2;
//
tcpData = (buffer+ipHeaderLen+tcpHeaderLen);
dataLen = HTONS(ipHeader->Len) - (ipHeaderLen + tcpHeaderLen);

Sau khi c c a ch IP ngun ca host gi v port ngun, port ch, ta tm kim trong TCP
session table phin TCP c sn tng ng vi gi tin ny, nu cha tn ti th khi to session
mi:

Code:
if(i == TCP_MAX_SESSION){ //Neu khong co 1 phien TCP dang ton tai cho goi nay
//Tim 1 phien dang o trang thai LISTEN (doi ket noi) cho local port nay
for(i=0; i < TCP_MAX_SESSION; i++){
if(tcpSessionTable[i].sesState == TCP_STATE_LISTEN){
if(tcpSessionTable[i].srcPort == HTONS((tcpHeader>desPort))){
//If matched local port
//Cap nhat remote port va remote IP
tcpSessionTable[i].desPort = HTONS((tcpHeader>srcPort));
tcpSessionTable[i].desIP = HTONL((ipHeader>srcIPAddr));
//Dong thoi tao ra 1 session moi de cho ket noi
khac den local port nay
TCPCreateSession(tcpSessionTable[i].srcPort,tcpSessionTable[i].appDataIn);
break;
}
}
}
}
if(i == TCP_MAX_SESSION){
#ifdef TCP_DEBUG
printf("No TCP session found\r\n");
#endif
return; //Neu khong co phien TCP nao danh cho goi nay thi thoat ra
}
#ifdef TCP_DEBUG
printf("TCP session found: %d\r\n",i);
#endif

Ta reset bin Timeout mi khi nhn c gi tin. Bin ny nhm pht hin v hy b cc phin
TCP b treo mt thi gian di m khng nhn c d liu.
Code:
tcpSessionTable[i].timeOut = TCP_TIMEOUT; //Reset lai gia tri Time out

Nu c RST=1 (Reset). ng kt ni.


Code:
if ((tcpHeader->Flags) & TCP_RST_FLAG){
//Chap nhan dong ket noi
TCPCloseSession(i);
return;
}

Tip theo, ta phi x l theo lu trng thi ca TCP. Ta dng 1 cu trc switchcase x l
ty vo trng thi hin ti ca kt ni:
Code:
switch (tcpSessionTable[i].sesState){
//Neu la trang thai doi ket noi: TCP_STATE_LISTEN
case(TCP_STATE_LISTEN):
break;
//Neu la trang thai TCP_STATE_SYN_RECEIVED
case(TCP_STATE_SYN_RECEIVED):
break;
//Truong hop ket noi da duoc thiet lap
case(TCP_STATE_ESTABLISHED):
break;

//Neu la trang thai doi LAST_ACK (2 phia deu san sang dong ket noi, dang
doi xac nhan ack cuoi cung)
case(TCP_STATE_LAST_ACK):
break;
//Truong hop ngat ket noi thu dong, da nhan co FIN tu remote host va xac
nhan
case(TCP_STATE_CLOSE_WAIT):
break;
//Truong hop dang o trang thai FIN WAIT 1 (da truyen du lieu xong,
// san sang dong ket noi va da gui di co FIN va dang cho ACK)
case(TCP_STATE_FIN_WAIT1):
break;
//Neu dang o trang thai FIN WAIT 2 (san sang dong ket noi va gui co FIN,
// phia ben kia da xac nhan nhung van chua san sang dong ket noi
case(TCP_STATE_FIN_WAIT2):
break;
case(TCP_STATE_TIMED_WAIT):
break;
case(TCP_STATE_CLOSING):
break;
default:
TCPCloseSession(i);
}

Trong mi trng thi, ta x l thng tin trong header TCP v chuyn trng thi tng ng. Mi
ngi t c nh

Bi 6: Cc giao thc lp ng dng


Giao thc DHCP:
- DHCP l mt giao thc c s dng phn phi ng cc tham s cu hnh TCP/IP cho cc
my tnh. Mt DHCP server c th cho client DHCP mt s thit lp TCP/IP, nh l a ch IP,
subnet mask, v my ch DNS.
- Mi client s nhn mt hp ng thu a ch trong thi gian hn nh. Nu client khng cn
s dng a ch khi hp ng thu ht hn, a ch c th cp pht cho cc client khc.
C ch lm vic ca DHCP: gm c 4 bn tin chnh:
+ DHCPDISCOVER: DHCP client khi to tin trnh bng cch qung b mt gi ti cng UDP
68 (s dng cho my ch BOOTP v DHCP). Gi u tin ny c gi l bn tin DHCP
Discover, n s yu cu bt c DHCP server no nhn c gi thc hin vic cu hnh. Gi
DHCP discover gm rt nhiu trng, nhng mt vng quan trng nht cha a ch vt l ca
DHCP client.

+ DHCPOFFER: Mt DHCP server c cu hnh cung cp hp ng a ch cho mng m client


c tr s p ng li mt gi tn l DHCP offer v gi n di dng qung b ti my a ra
DHCP discover. Thng ip qung b ny c gi ti cng UDP 67 v bao gm a ch vt l
ca client, a ch vt l v a ch IP ca DHCP server, cng nh gi tr a ch IP v subnet
mask cung cp cho DHCP client.

+ DHCPREQUEST: Client chn mt DHCP offer, to mt gi DHCP request v qung b gi ny.


Gi DHCP request ny bao gm a ch IP ca server pht ra DHCP offer v a ch vt l ca
DHCP client. DHCP request ny thc hin hai vic:
. Bo cho DHCP server c chn rng n yu cu mt a ch IP.
. Thng bo cho cc DHCP server khc l DHCP offer ca chng khng c chp nhn.

+ DHCPACK: Khi DHCP server c chn nhn c DHCP request, n s tr li bng gi DHCP
ack. DHCP ack bao gm a ch IP v subnetmask cho DHCP client. Ngoi cc thng tin v a
ch IP, DHCP client c th nhn thm cc thng tin cu hnh nh a ch IP ca gateway, my
ch DNS, ...

Nguyn vn bi tienhuypro

Hi anh Tm ! V em khng phi l dn IT nn c nhiu thc mc lm.


Cho em hi l trng hp gi ra ngoi mng LAN. phn 4a sau khi bit MAC ca gateway ri
phn gi tin cn gi n 203.162.44.164 th s thc hin nh th no vy.
Cu hi th 2: C khi no 2 a ch MAC trng nhau khng v nu trng th c phi lp IP dng
phn bit cc my tnh vi nhau khng.

Cu 1: Sau khi bit MAC ca gateway, host gi s gi gi IP n Gateway thng qua a ch


MAC ca n (a ch IP ch vn ghi l 203.162.44.164 nhng a ch MAC ch th l ca
Gateway).
Khi nhn c gi tin, Gateway (chnh l 1 router IP) s kim tra a ch mng ca a ch IP
ch (VD: trng hp a ch IP 203.162.44.164 th a ch mng l 203.162.44.0 - 24 bit u).
Sau n i chiu a ch mng ny vi mt bng, gi l bng nh tuyn (Routing table).
Trong bng nh tuyn c lu thng tin v cc a ch mng v giao tip mng tng ng m
gi tin phi c chuyn ti, cng nh a ch IP ca Router tip theo s chu trch nhim
chuyn gi tin i. Gateway s cn c vo cc thng tin ny chuyn gi tin i tip.
V d: ADSL router nh mnh c bng nh tuyn nh sau (c th truy cp vo trang cu hnh
modem xem c bng ny):

Gii thch:
- Destination: a ch ch, thng ch lu a phn ch mng.
- Subnet Mask: mt n mng con tng ng vi a ch ch .
- Next hop: router k tip s nhn nhim v chuyn gi tin.
- Metric: s chng (s router) m gi tin phi i qua n c ch ny (s dng cho cc
giao thc nh tuyn).
- Interface: giao din (hay kt ni mng) m router phi chuyn gi tin ra. Trong trng
hp ADSL router ca mnh, n ch c 2 interface: kt ni vo mng LAN bn trong (n t tn
l br0) v kt ni ra bn ngoi (n t tn l ppp0).
1-Dng u tin cho bit: nu a ch ch l 123.20.128.1 (y chnh l a ch ca Router bin
ca ISP m ADSL router ca mnh kt ni n), th n cn chuyn d liu ra giao tip
(interface) ppp0 (y chnh l kt ni WAN ca modem ADSL, xem thm cc minh ha s
mng bn di). Next hop= * c ngha l n khng cn thng qua router no khc na m c
kt ni trc tip n destination.
2-Dng th 2: nu ch l 192.168.0 (y l a ch ca mng LAN), th n phi chuyn gi tin
vo giao tip mng LAN bn trong (interface = br0). Tng t, khng c Next hop.
3-Dng th 3: nu ch l 127.0.0.0 (y l a ch loopback, gi cho chnh mnh) th n khng
chuyn ra giao tip no ht m l cho chnh n (Interface = lo).
4-Dng th 4: Mi trng hp a ch ch khc (Destination = 0.0.0.0; Subnet Mask =
0.0.0.0), n s chuyn ra giao tip mng bn ngoi (Interface = ppp0), v gi n router k
tip s chu trch nhim chuyn gi tin i l router bin ca ISP (a ch l 123.20.128.1)

V d minh ha:
y l s mng (a ch IP ca cc Router li ch la minh ha, khng chnh xc v mnh
khng c cc thng tin ny)

Bc 1: sau khi Gateway (ADSL router) nhn c gi tin c a ch ch l 203.162.44.164, n


s tra bng T ca n v thy tng ng vi dng ny (destination = 0.0.0.0), n s chuyn
gi tin ra giao tip mng WAN (ppp0) n router k tip l 123.20.128.1 (bng cch ghi a ch
MAC ca router k tip vo phn destination MAC Address trong frame ethernet).

Bc 2: Router bin ca ISP (123.20.128.1) nhn gi tin, tra trong bng T ca n, tm dng
tng ng, cn c vo n chuyn gi tin ra interface s 1 ca n (kt ni ti router li) v
gi n cho router li (123.20.64.1).

Bc 3: Router li ny nhn gi tin, li tra bng T ca n, sau chuyn gi tin ra interface 3


ca n n router li th hai (123.20.66.1).

Bc 4: Tng t, router li th hai nhn gi tin, tra bng v chuyn n router k l router
bin th hai (123.20.66.5) qua interface 3 ca n.

Bc 5: Cui cng, n lt router bin ng ra nhn gi tin, tra bng T, chuyn gi n


thng ch m khng cn qua router no na.

Cu 2: V l thuyt, mi nh sn xut c sn xut thit b mng s c cp mt khong a


ch MAC (cc byte u trong a ch MAC t 1 nh sn xut s ging nhau. V d: 3 byte u
ca 3com l: 00A024, ca Apple l 00A040,...). Sau khi sn xut ra mi thit b, nh sn
xut s nh s a ch MAC ca chng khc nhau. Nh vy, v l thuyt, a ch MAC khng
trng nhah.
Tuy nhin rt nhiu thit b (VD IC ENC28J60, nhiu loi card mng my tnh) cho php thay
i a ch MAC, do trong thc t, vic trng a ch MAC hon ton c th xy ra. Trong
trng hp : v d trong mng LAN c 2 my trng a ch MAC, khi d liu c gi lp
truy nhp mng (switch hay hub chuyn i) th ng thi c 2 my u nhn c nu d
liu gi cho 1 trong 2 my. Tuy nhin khi d liu c chuyn ln lp IP, a ch IP s c kim
tra (c th xem code ca phn giao thc IP thy vic kim tra ny), nu khng ng a ch
IP, d liu s b b qua.
Nu 2 my tnh trng a ch MAC nm 2 mng LAN khc nhau, vic ny s khng nh hng
g, v khi chuyn d liu gia cc mng LAN s do router thc hin, m nh ni trn,
router s cn c vo a ch IP ch khng phi a ch MAC.
Hy vng cu tr li ca mnh gii p c thc mc ca Huy, nu cha r c hi tip nh.
Mnh c cc slide vi animation minh hot cc hot ng ny, nhng khng bit lm sao post
ln, v dd khng h tr post flash th phi.
Nguyn vn bi rptdnmqs

Tha thy ,em xin hi my cu :


MAC gateway l mnh ly t modem ADSL?.Em gi gi arp request n a ch ip 192.168.1.1
(gateway) hi a ch MAC ca n c c k.Em thy trong code ca thy th gi
arp,ethernet,ip ch c phn header.Vy c phi ch c lp ng dng mi cha data?.Em mi vit
code n y thi.Em cm n thy nhiu.

Trong mng LAN dng Modem ADSL th gateway chnh l modem ADSL, do vy khi cn bit a
ch MAC ca n th ng nhin phi hi n ri, nhng y ta cha bit a ch MAC ca n
nn ta phi gi Broadcast (a ch IP ch = 192.168.1.1, MAC ch = FF:FF:FF:FF:FF:FF).
Gateway chnh l Router kt ni gia mng LAN vi bn ngoi. Trong trng hp ny chnh
l ADSL Router.
Trong phn giao thc ARP post, thc ra ti lch lut khi khng gi ARP request khi cha
bit a ch MAC m in lun a ch MAC broadcast vo gi tin cn gi i (ti c cc bn
pht hin ra ch lch lut ny m khng thy ai phn hi). rptdnmqs c bit ti sao phi lch
lut nh vy khng?
- Data ca ng dng cha trong phn data ca gi TCP hay UDP nm ngay sau Header
TCP/UDP.
- Gi IP th n xem ton b gi TCP/UDP l data ca n, v Header ca gi l Header IP.
- Tng t, frame Ethernet coi ton b gi IP l data ca n, Header l Header ca frame
ethernet.
- Vy gi ca giao thc no cng c data ht, c iu data ca n chnh l ton b gi ca giao
thc lp trn.
- Cn d liu ng dng trong gi TCP/UDP ng nhin l ch do lp ng dng to ra m thi.
L hn lu, hm nay tip tc vi giao thc DHCP, cn thng ny vi HTTP na l xong.
Trc ht, ta li to 2 file source v header:
"dhcp.c"
Code:
//---------------------------------------------------------------------------// Writen by NTTam - PTITHCM
//---------------------------------------------------------------------------#include "packet.h"
#include "ethernet.h"
#include "ip.h"
#include "udp.h"
#include "dhcp.h"
#include "uart.h"
#include "ntAVRnet.h"
//

"dhcp.h"
Code:
//---------------------------------------------------------------------------// Writen by NTTam - PTITHCM
//---------------------------------------------------------------------------#ifndef DHCP_H
#define DHCP_H
#include "packet.h"
//#define DHCP_DEBUG

Trong file Header, ta khai bo cc Header BOOTP v DHCP:


Code:
//---------------------------------------------------------------------------/// BOOTP Header
struct ntBootpHeader
{

unsigned char
opcode;
//Message op-code / message type
unsigned char
hwaddrtype;
//Hardware address type
(Ethernet=1)
unsigned char
hwaddrlen;
//Hardware address length (Ethernet=6
byte MAC addr)
unsigned char
hops;
//hop count (client set to zero)
unsigned long
transid;
//Transaction ID (randomly chosen by client,
must remain same)
unsigned int
secs;
//Seconds elapsed since DHCP
negotiation began (filled by client)
unsigned int
flags;
//Flags
unsigned long
clipaddr;
//Client IP address (filled only if
already bound, renewing, or rebinding)
unsigned long
yoipaddr;
//Your IP address (client)
unsigned long
seipaddr;
//Server IP address
unsigned long
gwipaddr;
//Gateway IP address
unsigned char
clhwaddr[16];
//Client Hardware Address
unsigned char
sename[64];
//Server Host Name
unsigned char
file[128];
//Boot file name (null-term string)
};
//
#define BOOTP_HEADER_LEN
236
//length of BOOTP header not including options
//
#define BOOTP_OP_BOOTREQUEST
1
//BOOTP Request operation (message from client
to server)
#define BOOTP_OP_BOOTREPLY
2
//BOOTP Reply operation (message from
server to client)
//
#define BOOTP_HTYPE_ETHERNET
1
//Hardware type for ethernet protocol
#define BOOTP_HLEN_ETHERNET
6
//Length of ethernet MAC address
//---------------------------------------------------------------------------struct netDhcpHeader
{
struct ntBootpHeader bootp;
//BOOTP header
unsigned long
cookie;
//magic cookie value
unsigned char
options[1];
//DHCP options
};
//
#define DHCP_HEADER_LEN
240
//length of DHCP header not including
options

Tip theo ta nh ngha 1 s gi tr hng c qui nh cho cc trng trong header:


Code:
//Code for DHCP option field
#define DHCP_OPT_PAD
skipped)
#define DHCP_OPT_NETMASK
#define DHCP_OPT_ROUTERS
#define DHCP_OPT_TIMESERVERS
#define DHCP_OPT_NAMESERVERS
#define DHCP_OPT_DNSSERVERS
addr list)
#define DHCP_OPT_HOSTNAME
#define DHCP_OPT_DOMAINNAME
(string)
#define DHCP_OPT_REQUESTEDIP
#define DHCP_OPT_LEASETIME
#define DHCP_OPT_DHCPMSGTYPE
#define DHCP_OPT_SERVERID
#define DHCP_OPT_PARAMREQLIST
#define DHCP_OPT_RENEWALTIME
#define DHCP_OPT_REBINDTIME
seconds)
#define DHCP_OPT_CLIENTID

//token padding value (make be

1
3
4
5

//subnet mask client should use (4 byte mask)


//routers client should use (IP addr list)
//time servers client should use (IP addr list)
//name servers client should use (IP addr list)
6
//DNS servers client should use (IP

12

//host name client should use (string)


15
//domain name client should use

50

//IP address requested by client (IP address)


51
//DHCP Lease Time (uint32 seconds)
//DHCP message type (1 byte)
//Server Identifier (IP address)
//Paramerter Request List (n OPT codes)
//DHCP Lease Renewal Time (uint32 seconds)
59
//DHCP Lease Rebinding Time (uint32

53
54
55
58
61

//DHCP Client Identifier

#define DHCP_OPT_END
255 //token end value (marks end of options
list)
//Code for DHCP message type
#define DHCP_MSG_DHCPDISCOVER
1
//DISCOVER is broadcast by client to solicit
OFFER from any/all DHCP servers.
#define DHCP_MSG_DHCPOFFER
2
//OFFER(s) are made to client by
server to offer IP address and config info.
#define DHCP_MSG_DHCPREQUEST
3
//REQUEST is made my client in response to
best/favorite OFFER message.
#define DHCP_MSG_DHCPDECLINE
4
//DECLINE may be sent by client to server to
indicate IP already in use.
#define DHCP_MSG_DHCPACK
5
//ACK is sent to client by server in
confirmation of REQUEST, contains config and IP.
#define DHCP_MSG_DHCPNAK
6
//NAK is sent to client by server to indicate
problem with REQUEST.
#define DHCP_MSG_DHCPRELEASE
7
//RELEASE is sent by client to server to
relinquish DHCP lease on IP address, etc.
#define DHCP_MSG_DHCPINFORM
8
//INFORM is sent by client to server
to request config info, IP address configured locally.

nh ngha port UDP c qui nh dnh cho giao thc BOOTP v DHCP, v gi tr timeout (s
giy ch tr li sau khi gi DHCP discover), s ln c gng nhn a ch IP thng qua DHCP:
Code:
#define
#define
//
#define
#define

DHCP_UDP_SERVER_PORT
DHCP_UDP_CLIENT_PORT
DHCP_TIMEOUT
DHCP_RETRIES

67
68

//UDP port where DHCP requests should be sent


//UDP port clients will receive DHCP replies

10
3

By gi ta m file source v bt u vit code:


Trc ht ta khai bo cc bin s dng :
Code:
//-------------------------------------------------------------------------------------unsigned long DhcpServerIP;
unsigned long DhcpTransactID;
unsigned long DhcpLeaseTime;
unsigned char macaddr[6];
//
unsigned char DhcpTimeout;
unsigned char DhcpRetries;

Vit hm khi to giao thc DHCP:


Code:
//-------------------------------------------------------------------------------------//Ham khoi tao cac thong so ban dau cho DHCP
void dhcpInit(void)
{
ethGetMacAddress(macaddr);
DhcpTransactID = *((unsigned long*)&macaddr[0]);
DhcpLeaseTime = 0;
DhcpTimeout = 1;
DhcpRetries = DHCP_RETRIES;
}

Hm ghi gi tr vo trng option ca DHCP, mi trng option s bt u bng 1 byte option


code, tip n l 1 byte chiu di ca gi tr option, theo sau l cc byte gi tr ca option:
Code:

//-------------------------------------------------------------------------------------//Ham set cac option cua DHCP


unsigned char* dhcpSetOption(unsigned char* options, unsigned char optcode, unsigned char
optlen, void* optvalptr)
{
*options++ = optcode;
*options++ = optlen;
while(optlen--)
{
*options++ = *(unsigned char*)optvalptr++;
}
*options = DHCP_OPT_END;
return options;
}

Hm c gi tr t trng option vo 1 bin:


Code:
//-------------------------------------------------------------------------------------//Ham lay cac option cua DHCP
unsigned char dhcpGetOption(unsigned char* options, unsigned char optcode, unsigned char
optlen, void* optvalptr)
{
unsigned char i;
for (;;)
{
if(*options == DHCP_OPT_PAD)
options++;
else if(*options == DHCP_OPT_END)
break;
else if(*options == optcode)
{
optlen = ((optlen<*(options+1))?(optlen):(*(options+1)));
for(i=0; i<optlen; i++)
*(((uint8_t*)optvalptr)+i) = *(options+i+2);
return *(options+1);
}
else
{
options++;
options+=*options;
options++;
}
}
return 0;
}

Hm xut ra cng serial Header ca bn tin (dng cho mc ch debug) :


Code:
//-------------------------------------------------------------------------------------#ifdef DHCP_DEBUG
//Ham de in Header goi DHCP (de debug)
void dhcpPrintHeader(struct netDhcpHeader* packet)
{
printf("DHCP Packet:\r\n");
// print op
printf("Op
: ");
switch(packet->bootp.opcode)
{
case BOOTP_OP_BOOTREQUEST:
printf("BOOTREQUEST"); break;
case BOOTP_OP_BOOTREPLY: printf("BOOTREPLY"); break;
default:
printf("UNKNOWN"); break;

}
printf("\n\r");
// print transaction ID
printf("XID
: 0x"); /*rprintfu32(packet->bootp.transid);*/
printf("\n\r");
// print client IP address
printf("ClIpAddr: ");
ipPrintAddr(HTONL(packet->bootp.clipaddr));
printf("\n\r");
// print 'your' IP address
printf("YrIpAddr: ");
ipPrintAddr(HTONL(packet->bootp.yoipaddr));
printf("\n\r");
// print server IP address
printf("SvIpAddr: ");
ipPrintAddr(HTONL(packet->bootp.seipaddr));
printf("\n\r");
// print gateway IP address
printf("GwIpAddr: ");
ipPrintAddr(HTONL(packet->bootp.gwipaddr));
printf("\n\r");
// print client hardware address
printf("ClHwAddr: ");
ethPrintAddr((struct ntEthAddr*)packet>bootp.clhwaddr);
printf("\n\r");
}
#endif

Hm gi i bn tin DHCP discover :


Code:
//-------------------------------------------------------------------------------------//Ham gui di mot ban tin DHCP discover de tim kiem DHCP server
void dhcpDiscover(void)
{
struct netDhcpHeader* packet;
unsigned long val;
unsigned char* optptr;
packet = (struct netDhcpHeader*)(ethGetBuffer() + ETH_HEADER_LEN + IP_HEADER_LEN
+ UDP_HEADER_LEN);
//
packet->bootp.opcode = BOOTP_OP_BOOTREQUEST;
packet->bootp.hwaddrtype = BOOTP_HTYPE_ETHERNET;
packet->bootp.hwaddrlen = BOOTP_HLEN_ETHERNET;
packet->bootp.clipaddr = HTONL(ipGetConfig()->ip);
packet->bootp.yoipaddr = HTONL(0l);
packet->bootp.seipaddr = HTONL(0l);
packet->bootp.gwipaddr = HTONL(0l);
ethGetMacAddress(&packet->bootp.clhwaddr[0]);
packet->bootp.transid = DhcpTransactID;
packet->bootp.flags = HTONS(1);
//
packet->cookie = 0x63538263;
val = DHCP_MSG_DHCPDISCOVER;
optptr = dhcpSetOption(packet->options, DHCP_OPT_DHCPMSGTYPE, 1, &val);
dhcpSetOption(optptr, DHCP_OPT_CLIENTID, 6, macaddr);
#ifdef DHCP_DEBUG
printf("DHCP: Sending Query\r\n");
dhcpPrintHeader(packet);
#endif
udpSend(0xFFFFFFFF, DHCP_UDP_SERVER_PORT, DHCP_UDP_CLIENT_PORT,
DHCP_HEADER_LEN+3+1+8, (unsigned char*)packet);
}

Hm gi bn tin DHCP request p ng li cho DHCP offer :


Code:

//-------------------------------------------------------------------------------------//Ham gui di mot ban tin DHCP request de yeu cau nhan dia chi IP
void dhcpRequest(struct netDhcpHeader* packet, unsigned long serverid)
{
unsigned char* optptr;
unsigned long val;
packet->bootp.opcode = BOOTP_OP_BOOTREQUEST;
// request type
val = DHCP_MSG_DHCPREQUEST;
optptr = dhcpSetOption(packet->options, DHCP_OPT_DHCPMSGTYPE, 1, &val);
optptr = dhcpSetOption(optptr, DHCP_OPT_CLIENTID, 6, macaddr);
optptr = dhcpSetOption(optptr, DHCP_OPT_SERVERID, 4, &serverid);
optptr = dhcpSetOption(optptr, DHCP_OPT_REQUESTEDIP, 4, &packet->bootp.yoipaddr);
((unsigned char*)&val)[0] = DHCP_OPT_NETMASK;
((unsigned char*)&val)[1] = DHCP_OPT_ROUTERS;
((unsigned char*)&val)[2] = DHCP_OPT_DNSSERVERS;
((unsigned char*)&val)[3] = DHCP_OPT_DOMAINNAME;
optptr = dhcpSetOption(optptr, DHCP_OPT_PARAMREQLIST, 4, &val);
packet->bootp.yoipaddr = HTONL(0l);
#ifdef DHCP_DEBUG
printf("DHCP: Sending request in response to offer\r\n");
#endif
udpSend(0xFFFFFFFF, DHCP_UDP_SERVER_PORT, DHCP_UDP_CLIENT_PORT,
DHCP_HEADER_LEN+3+6+6+6+8+1, (unsigned char*)packet);
}

Hm x l gi DHCP nhn c, hm ny s c gi bi giao thc UDP:


Code:
//-------------------------------------------------------------------------------------//Ham xu ly mot goi DHCP nhan duoc
void dhcpIn(unsigned int len, struct netDhcpHeader* packet)
{
unsigned char msgtype;
unsigned long sid;
unsigned long netmask;
unsigned long gateway;
unsigned long val;
//
#ifdef DHCP_DEBUG
dhcpPrintHeader(packet);
#endif
//
if((packet->bootp.opcode != BOOTP_OP_BOOTREPLY) || (packet->bootp.transid !=
DhcpTransactID))
return;
//
dhcpGetOption(packet->options, DHCP_OPT_DHCPMSGTYPE, 1, &msgtype);
#ifdef DHCP_DEBUG
printf("DHCP: Received msgtype = %d\r\n", msgtype);
#endif
//
if(msgtype == DHCP_MSG_DHCPOFFER)
{
dhcpGetOption(packet->options, DHCP_OPT_SERVERID, 4, &sid);
#ifdef DHCP_DEBUG
printf("DHCP: Got offer from server "); ipPrintAddr(HTONL(sid));
printf("\n\r");
#endif
dhcpRequest(packet, sid);
}
//
else if(msgtype == DHCP_MSG_DHCPACK)
{

dhcpGetOption(packet->options, DHCP_OPT_NETMASK, 4, &val);


netmask = HTONL(val);
//
dhcpGetOption(packet->options, DHCP_OPT_ROUTERS, 4, &val);
gateway = HTONL(val);
//
dhcpGetOption(packet->options, DHCP_OPT_LEASETIME, 4, &val);
DhcpLeaseTime = HTONL(val);
//
ipSetConfig(HTONL(packet->bootp.yoipaddr), netmask, gateway);
//
DhcpRetries = 0;
#ifdef DHCP_DEBUG
printf("DHCP: Got request ACK, bind complete\r\n");
ipPrintConfig(ipGetConfig());
printf("LeaseTm : %d\n\r", DhcpLeaseTime);
#endif
}
}

Hm hy b a ch IP hin ti:
Code:
//-------------------------------------------------------------------------------------//Ham release dia chi IP hien tai va xoa cac thong so cau hinh IP dang co
void dhcpRelease(void)
{
struct netDhcpHeader* packet;
unsigned long val;
unsigned char* optptr;
//
packet = (struct netDhcpHeader*)&ethGetBuffer()
[ETH_HEADER_LEN+IP_HEADER_LEN+UDP_HEADER_LEN];
//
packet->bootp.opcode = BOOTP_OP_BOOTREQUEST;
packet->bootp.hwaddrtype = BOOTP_HTYPE_ETHERNET;
packet->bootp.hwaddrlen = BOOTP_HLEN_ETHERNET;
packet->bootp.clipaddr = HTONL(ipGetConfig()->ip);
packet->bootp.yoipaddr = HTONL(0l);
packet->bootp.seipaddr = HTONL(0l);
packet->bootp.gwipaddr = HTONL(0l);
ethGetMacAddress(&packet->bootp.clhwaddr[0]);
packet->bootp.transid = DhcpTransactID;
packet->bootp.flags = HTONS(1);
//
packet->cookie = 0x63538263;
//
val = DHCP_MSG_DHCPRELEASE;
optptr = dhcpSetOption(packet->options, DHCP_OPT_DHCPMSGTYPE, 1, &val);
//
val = HTONL(DhcpServerIP);
optptr = dhcpSetOption(optptr, DHCP_OPT_SERVERID, 4, &val);
//
optptr = dhcpSetOption(optptr, DHCP_OPT_REQUESTEDIP, 4, &packet->bootp.clipaddr);
//
#ifdef DHCP_DEBUG
printf("DHCP: Sending Release to "); ipPrintAddr(DhcpServerIP); printf("\n\r");
#endif
udpSend(DhcpServerIP, DHCP_UDP_SERVER_PORT, DHCP_UDP_CLIENT_PORT,
DHCP_HEADER_LEN+3+6+6+1, (unsigned char*)packet);
ipSetConfig(0,0,0);
DhcpLeaseTime = 0;
}

Hm cp nht cc bin thi gian m DHCP s dng (c gi 1s/ln bi timer):


Code:
//-------------------------------------------------------------------------------------//Ham duoc goi dinh ky moi 1s de cap nhat lease time va timeout cua DHCP
void dhcpTimer(void)
{
// this function to be called once per second
// decrement lease time
if(DhcpLeaseTime)
DhcpLeaseTime--;
if(DhcpTimeout){
DhcpTimeout--;
}
}

Hm dch v DHCP, ta s a vo vng lp chng trnh chnh:


Code:
//-------------------------------------------------------------------------------------//Ham dich vu DHCP, duoc goi trong chuong trinh chinh
void dhcpService(void)
{
if(DhcpRetries && (DhcpTimeout == 0)){
DhcpRetries--;
DhcpTimeout = DHCP_TIMEOUT;
dhcpDiscover();
}
}
//--------------------------------------------------------------------------------------

Vy l xong file source v header cho DHCP, cc bn nh thm khai bo hm vo file header
nh

Tip theo, c th chy th giao thc DHCP, chng ta cn modify source c mt t b sung
giao thc ny vo:
1-M file timer.h sa define cho prescale ca timer thnh 1024 timer chy ng, ngt
1s/ln (vi thch anh 12MHz nha cc bn):
Code:
#define TIMER1PRESCALE

TIMER_CLK_DIV1024

2-M file udp.c, sa hm udpSend b sung source port vo trong hm, thm lnh gi hm
ca giao thc DHCP vo hm UDPProcess:
Code:
//---------------------------------------------------------------------------// Writen by NTTam - PTITHCM
//---------------------------------------------------------------------------#include "packet.h"
#include "ip.h"
#include "uart.h"
#include "dhcp.h"
//#define UDP_DEBUG
//---------------------------------------------------------------------------//Ham gui di mot goi UDP
void udpSend(unsigned long dstIp, unsigned int dstPort, unsigned int srcPort, unsigned
int len, unsigned char* udpData)
{
struct ntUDPHeader* udpHeader;

udpHeader = (struct ntUDPHeader*)(udpData - UDP_HEADER_LEN);


len += UDP_HEADER_LEN;
udpHeader->desPort = HTONS(dstPort);
udpHeader->srcPort = HTONS(srcPort);
udpHeader->Len = HTONS(len);
udpHeader->Checksum = 0;
ipSend(dstIp, IP_PROTO_UDP, len, (unsigned char*)udpHeader);
}
//-------------------------------------------------------------------------------------//Ham xu ly goi UDP nhan duoc, duoc goi boi ham xu ly goi IP (IPProcess)
// Hien chua co ung dung chay UDP nen ham nay trong
void UDPProcess(unsigned int len, struct ntIPHeader* packet)
{
dhcpIn((len - IP_HEADER_LEN - UDP_HEADER_LEN), (struct netDhcpHeader*)
((char*)packet + IP_HEADER_LEN + UDP_HEADER_LEN));
#ifdef UDP_DEBUG
printf("Rx UDP Packet\r\n");
#endif
}
//--------------------------------------------------------------------------------------

(Nh cp nht khai bo hm bn file header nha)


3-Thm mt s include (khi dch bo li th cc bn cng t tm ra m thm vo thi, ch lun
cho mc cng kim):
#include <avr/pgmspace.h>//// vo tcp.h
#include "dhcp.h"//// vo ntAVRnet.h
#include "udp.h" v #include "icmp.h" vo ip.h
4-Sa hm IPProcess, thm cc lnh gi hm ca giao thc UDP, TCP vo:
Code:
void IPProcess(unsigned int len, struct ntIPHeader* packet)
{
// check IP addressing, stop processing if not for me and not a broadcast
if( (HTONL(packet->desIPAddr) != ipGetConfig()->ip) &&
(HTONL(packet->desIPAddr) != (ipGetConfig()->ip|ipGetConfig()->netmask))
&&
(HTONL(packet->desIPAddr) != 0xFFFFFFFF) &&
(ipGetConfig()->ip != 0x00000000) )
return;
// handle ICMP packet
if( packet->Protocol == IP_PROTO_ICMP )
{
#ifdef IP_DEBUG
printf("IP->Rx: ICMP/IP packet\r\n");
//icmpPrintHeader((icmpip_hdr*)packet);
#endif
icmpIpIn((struct ntIPHeader*)packet);
}
else if( packet->Protocol == IP_PROTO_UDP )
{
#ifdef IP_DEBUG
printf("IP->Rx: UDP/IP packet\r\n");
//debugPrintHexTable(NetBufferLen-14, &NetBuffer[14]);
#endif
UDPProcess(len, ((struct ntIPHeader*)packet) );////
}
else if( packet->Protocol == IP_PROTO_TCP )
{
#ifdef IP_DEBUG

printf("IP->Rx: TCP/IP packet\r\n");


#endif
TCPProcess((unsigned char *)packet,len-((packet->verHdrLen &
0x0F)<<2));////
}
else
{
#ifdef IP_DEBUG
printf("IP->Rx: IP packet\r\n");
#endif
}
}
//--------------------------------------------------------------------------------------

5-M hm ngt timer 1 (trong file timer.h), thm vo cc hm cp nht thi gian ca giao thc
TCP v DHCP vo:
Code:
TIMER_INTERRUPT_HANDLER(SIG_OVERFLOW1)
{
//Tai nap gia tri timer 1
TCNT1 = 0xFFFF - TIMER1_INTERVAL;
//Cap nhat watchdog timer
if((time_watchdog++) > 120){
time_watchdog = 0;
ethInit();
}
Counter1s++;
arpTimer();
TCPCheckTimeOut();////
dhcpTimer();////
}

6-Thm vo hm main trong file ntAVRnet.h


Code:
int
{

main()
SystemInit();
printf("\r\nNTTam AVR network testing with enc28j60.\r\n");
printf("Initializing Network Interface and Stack\r\n");
printf("Ethernet chip init\r\n");
IpMyConfig.ethaddr.addr[0] = ETHADDR0;
IpMyConfig.ethaddr.addr[1] = ETHADDR1;
IpMyConfig.ethaddr.addr[2] = ETHADDR2;
IpMyConfig.ethaddr.addr[3] = ETHADDR3;
IpMyConfig.ethaddr.addr[4] = ETHADDR4;
IpMyConfig.ethaddr.addr[5] = ETHADDR5;
IpMyConfig.ip = IPADDRESS;
IpMyConfig.netmask = NETMASK;
IpMyConfig.gateway = GATEWAY;
netInit(IpMyConfig.ip, IpMyConfig.netmask, IpMyConfig.gateway);
PrintIPConfig();
printf("Getting IP Address....\r\n");
if(IpMyConfig.ip == 0x00000000){
dhcpInit();
}
while(1)
{
ethService();
dhcpService();
}
return 0;

By gi nu lc u mch ca ta cha c a ch IP (IP address l 0.0.0.0) th n s khi to


giao thc DHCP nhn a ch IP.
th, ta chnh li cc thng s cu hnh IP trong file ntAVRnet.h nh sau:
Code:
#define IPDOT(a,b,c,d)
((unsigned long)((unsigned char)a)<<24)+((unsigned long)
((unsigned char)b)<<16)+((unsigned long)((unsigned char)c)<<8)+(unsigned char)d//
((a<<24)|(b<<16)|(c<<8)|(d))
//#define IPADDRESS
IPDOT(192,168,1,10)
#define IPADDRESS
IPDOT(0,0,0,0)
#define NETMASK
IPDOT(0,0,0,0)
#define GATEWAY
IPDOT(0,0,0,0)

By gi ta c th bin dch, ni cp mng v m ngun, i board nhn a ch IP (nh kt ni


cng COM cn bit n nhn c a ch bao nhiu nh).
Phn code ny ch khi ng DHCP lc mi reset mch thi nh, cha h tr hot plug cp
mng

. Cc bn c th t sa code thm phn ny vo.

Bi 7: Giao thc HTTP


- HTTP l ch vit tt t HyperText Transfer Protocol (giao thc truyn ti siu vn bn). N l
giao thc c bn m World Wide Web s dng truyn ti ni dung cc trang web. HTTP xc
nh cch cc thng ip (cc file vn bn, hnh nh ho, m thanh, video, v cc file
multimedia khc c nh dng v truyn ti ra sao, v hot ng ca Web server v cc trnh
duyt Web.
- Trong m hnh ca HTTP, Webserver ng thi cng l TCP server, m sn port mc nh dnh
cho dch v HTTP l TCP80 ( ch listen), sn sng i yu cu kt ni t cc client.
- Cc client s khi to kt ni TCP thng qua port ny, sau khi Webserver chp nhn kt ni,
client s gi mt bn tin HTTP (HTTP message) gi l HTTP request ti server trn kt ni TCP
va thit lp.
- Server s tr li li bng mt bn tin HTTP khc l HTTP response. Bn tin ny s cha ni
dung trang Web yu cu (c vit bng ngn ng HTML).
Nh vy giao thc HTTP s da c bn trn cc bn tin HTTP, gm 2 loi l HTTP request v
HTTP response.
Gi s ngi dng truy cp URL: www.dientuvietnam.net/index.html (trang web c text v 10
hnh nh jpeg):
1a-HTTP client thit lp lin kt TCP vi HTTP server (process) ti a ch
www.dientuvietnam.net, cng 80 (ngm nh cho dch v HTTP).
1b-HTTP server ti my ch www.dientuvietnam.net ch yu cu kt ni TCP ti cng 80, chp
nhn kt ni ri thng bo vi client.
2-HTTP client gi HTTP request message (bao gm c URL) ti TCP connection socket.
3-HTTP server nhn request message, to ra HTTP response message c cha cc i tng
c yu cu ri gi vo socket.

4-HTTP server ngt lin kt.


5-HTTP client nhn response message c cha file html, hin th html. Sau , phn tch file
html, tm URL ca 10 hnh nh jpeg trong ti liu.
6-Bc 1-5 c lp li vi tng hnh nh.
C nhiu phin bn HTTP, tuy nhin y chng ta s bt u vi phin bn HTTP n gin
nht: HTTP 1.0
1-Cu trc cc bn tin HTTP:
Bn tin HTTP (HTTP message) gm 2 loi: HTTP request v HTTP response. i vi HTTP
request ta c Simple-Request v Full-Request. Tng t ta cng c Simple-Response v FullResponse.
1.1-Bn tin HTTP request:

a-Simple-Request: c cu trc rt n gin


GET<space><Request-URI><CRLF>
b-Full-Request: c cu trc tng qut gm c 3 phn nh sau
[Request-Line]
[Headers]
<CRLF>
[Entity-Body]
Request-Line: c c php nh sau:
<Method><space><Request-URI><space><HTTP-Version><CRLF>
Trong :
- Method l tn phng thc HTTP, vi HTTP 1.0 ta c cc method chnh l: "GET", "HEAD" v
"POST".
- Request-URI l ng dn ti trang web cn ti, c th l ng dn tng i hay tuyt i.
- HTTP-Version: cho bit phin bn HTTP ang s dng.
V d:
- Request line vi URI tuyt i:
GET http://www.w3.org/pub/WWW/TheProject.html HTTP/1.0
- Request line vi URI tng i:
GET /pub/WWW/TheProject.html HTTP/1.0
Headers: c 3 loi: General-Header; Request-Header; Entity-Header
C nhiu Header khc nhau trong mi loi, y khng tin trnh by ht, nhng nhn chung,
HTTP Header c c php nh sau:

<field-name>: <field-value> <CRLF>


Entity-Body: cha cc thng tin km theo request (v d khi ta nhn nt Submit trn 1
trang web s dng phng thc HTTP POST, trng thi ca cc nt check, gi tr trong cc
edit text,... s c cha trong phn ny.
V d:
- Mt bn tin HTTP request dng phng thc GET:
GET /path/file.html HTTP/1.0<CRLF>
From: someuser@jmarshall.com<CRLF>
User-Agent: HTTPTool/1.0<CRLF>
<CRLF>
Trong phng thc GET ny, phn body l trng (khng c message body)
- Mt bn tin HTTP request dng phng thc POST:
POST /path/script.cgi HTTP/1.0<CRLF>
From: frog@jmarshall.com<CRLF>
User-Agent: HTTPTool/1.0<CRLF>
Content-Type: application/x-www-form-urlencoded<CRLF>
Content-Length: 32<CRLF>
<CRLF>
home=Cosby&favorite+flavor=flies
Dng
Dng
Dng
Dng

1 l request line
2,3,4,5 l cc header
6 ch cha 1 k t xung dng (<CRLF>) bo ht phn Header, bt u mesage body
7 chnh l phn body

y chng ta cn lu l di Headers khng c nh, nhng kt thc bng <CRLF>. Do


khi vit chng trnh cho AVR, ta s tm ch no c 2 k t <CRLF> lin tip th l kt
thc Headers.
1.1-Bn tin HTTP response:

a-Simple-Response: c cu trc rt n gin, ch cha phn Entity-Body


[Entity-Body]
b-Full-Response: c cu trc tng qut gm c 3 phn nh sau
<Status-Line>
<Headers>
<CRLF>
[Entity-Body]
Status-Line: c c php nh sau
<HTTP-Version><space><Status-Code><Space><Reason-Phrase><CRLF>
Trong :
- HTTP-Version: cho bit phin bn giao thc HTTP. V d: "HTTP/1.0"

- Status-Code: cho bit m trng thi ca response. Gm 3 ch s, c qui nh nh sau


+ 1xx: Informational - cha c s dung, d phng
+ 2xx: Thnh cng (Success) - cho bit request c chp nhn v p u.
+ 3xx: Chuyn hng (Redirection) - yu cu client chuyn hng request
+ 4xx: Li do client (Client Error) - request khng hp l
+ 5xx: Li do sever (Server Error) - request hp l nhng server b li khng th tr li
Cc Status-Code c th hay dng:
+ "200" ; OK
+ "201" ; Created
+ "202" ; Accepted
+ "204" ; No Content
+ "301" ; Moved Permanently
+ "302" ; Moved Temporarily
+ "304" ; Not Modified
+ "400" ; Bad Request
+ "401" ; Unauthorized
+ "403" ; Forbidden
+ "404" ; Not Found
+ "500" ; Internal Server Error
+ "501" ; Not Implemented
+ "502" ; Bad Gateway
+ "503" ; Service Unavailable
- Reason-Phrase: cha ni dung text gii thch cho response.
Headers: c php tng t header ca request, cng gm General-Header; Response-Header;
Entity-Header
Entity-Body:cha phn ni dung tr li ca response (v du ni dung file html)
V d: Mt response cho phng thc GET
HTTP/1.0 200 OK<CRLF>
Date: Fri, 31 Dec 1999 23:59:59 GMT<CRLF>
Content-Type: text/html<CRLF>
Content-Length: 1354<CRLF>
<CRLF>
<html>
<body>
<h1>Happy New Millennium!</h1>
(more file contents)
.
.
.
</body>
</html>
Dng 1: Status-Line
Dng 2: General Header
Dng 3,4: Entity-Header

Dng 5: <CRLF>, bo hiu kt thc headers


Dng 6 tr i: Entity body
Ngn ng HTML v thit k web cho AVR webserver:
Phn ny khng bit phi trnh by sao na, v gii thch v HTML v thit k web th di dng
qu, nn ch hng dn cc bn lm 1 trang web n gin nhng vo AVR thi.
u tin ta dng bt c 1 phn mm c h tr thit k web no cng c, microsoft ofice
word, microsoft ofice frontpage, ofice publisher, ... (mnh dng Adobe Dreamweaver CS5 do
sn tin ang dng vit PHP) thit k 1 trang web n gin tng t nh sau:

Bn no cha bit lm hoc li c th lm nh sau:


1-M notepad.
2-Copy code html sau vo:
Code:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" dir="ltr" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>AVR web server</title>
</head>
<body style="background: #048C04; color: #FFFFFF">
<br>
<table bgcolor="#489D48" border="0" width="975" cellpadding="0" cellspacing="0"
align="center">
<tbody>
<tr>

<td height="31" align="center">


<div style="font-size:48pt; color:#F4FC8F"><strong>REMOTE CONTROL AVR
WEBSERVER</strong></div>
</td>
</tr>
</tbody>
</table>
<table width="100%" cellpadding="0" cellspacing="0">
<tbody>
<tr>
<td>
<br>
<div align="center">
<div style="background: #ffffff; color: #000000; width:975px; text-align:left">
<div style="padding:0px 15px 0px 15px" align="left">
<br>
<table style="background: #999999; color: #000000; border: 1px solid #6581c1"
cellpadding="6" cellspacing="1" border="0" width="100%" align="center">
<tbody>
<tr style="background: #FFFFFF; color: #545454; border-left: 1px solid #FFFFFF;
border-top: 1px solid #FFFFFF">
<td width="100%">
<div style="font-size:10pt"><strong>DESIGNER: THANH - TAM</strong></div>
</td>
<td nowrap="nowrap" style="padding:0px">
</td>
</tr>
</tbody>
</table>
<br>
<table style="background: #999999; color: #000000; border: 1px solid #6581c1"
cellpadding="6" cellspacing="1" border="0" width="100%" align="center">
<thead>
<tr valign="top">
<td style="background: #FFFFFF; color: #048C04" colspan="3"><strong>Remote
control webserver with ATmega32</a></strong></td>
</tr>
</thead>
<tbody id="collapseobj_vietvbb_stats" style="">
<tr>
<td style="background: #FFFFFF; color: #545454; border-left: 1px solid
#FFFFFF; border-top: 1px solid #FFFFFF">
<table border="1" cellpadding="0" cellspacing="0" width="100%">
<tbody>
<tr style="font-size:12pt">
<td style="padding: 5px 5px 5px 5px;" width="25%">
<div>
<strong>Camera view</strong>
</div>
</td>
<td style="padding: 5px 5px 5px 5px;" width="25%">
<div>
<strong>Devices control</strong>
</div>
</td>
<td style="padding: 5px 5px 5px 5px;" width="50%">
<div>
<strong>Sensors</strong>
</div>
</td>
</tr>
<tr style="font:bold 12pt">
<td style="padding: 5px 5px 5px 5px;" width="25%">

<div id="vietvbb_topstats_s_content" style="display: block;">


<img
src="http://d.f5.photo.zdn.vn/upload/original/2011/06/19/1/24/1308421475585659804_574_0.j
pg" width="320" height="240" />
</div>
</td>
<td style="padding: 5px 5px 5px 5px;" width="25%">
<div>
<form method="POST" action="">
<p align="left"><input type="checkbox" name="RELAY1"
value="ON"%RL1>Relay 01</p>
<p align="left"><input type="checkbox" name="RELAY2"
value="ON"%RL2>Relay 02</p>
<p align="left"><input type="checkbox" name="RELAY3"
value="ON"%RL3>Relay 03</p>
<p align="left"><input type="checkbox" name="RELAY4"
value="ON"%RL4>Relay 04</p>
<p align="left"><input type="submit" value="Submit" name="CTRL"></p>
</form>
</div>
</td>
<td style="padding: 5px 5px 5px 5px;" width="50%">
<div>
<table border="1" width="100%" id="table1">
<tr>
<td>Environment Sensors</td>
<td width="42">Value</td>
<td width="33">Unit</td>
<td width="150">&nbsp;</td>
</tr>
<tr>
<td>Sensor 01</td>
<td width="42">%AD0</td>
<td width="33"><sup>o</sup>C</td>
<td width="150">&nbsp;</td>
</tr>
<tr>
<td>Sensor 02</td>
<td width="42">%AD1</td>
<td width="33"><sup>o</sup>C</td>
<td width="150">&nbsp;</td>
</tr>
</table>
</div>
</td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
<br><br><br>
<div align="center">Timezone: GMT+7. Current time <span>%TI</span>.</div>
<br>
</div>
</div>
</div>
<form action="footer" method="get">
<br>
<div align="center">
<div align="center">Designed by thanh - tam</div>
</div>

</form>
</td>
</tr>
</tbody>
</table>
</div>
</body>
</html>

3-Chn Save as: Chn Save as type: All file; Encoding: UTF-8; t tn file l web.html (nh
ng ui nh).
4-Dng trnh duyt m xem th.
5-Dng Microsoft Office word hay bt c phn mm son tho web no edit li theo mnh.
on code trn chnh l m HTML m t ni dung trang web m webserver phi tr li li cho 1
bn tin HTTP request (GET hay POST)
Trong trang web trn ta c 1 hnh nh (ch cn nh mnh) nhng ta khng lu hnh nh ny
trn ROM m upload trn 1 server khc ri nhng code vo thi, tit kim b nh cho AVR.
Nh vy kch bn truy cp vo webserver vi trang web trn nh sau (gi s ta ch mi truy
cp trong mng LAN vi IP ca mch l 192.168.1.10):
1-Webserver (mch AVR+ENC28J60) m sn cng TCP 80 (listen) i nhn kt ni t client.
2-Ta m trnh duyt, g a ch http://192.168.1.10
3-My tnh khi to 1 kt ni TCP ti a ch IP 192.168.1.10, port ch l 80, port ngun do n
t chn (gi bn tin SYN).
4-Webserver chp nhn kt ni (tr li bn tin SYN), client xc nhn ACK (xem li phn giao
thc TCP). Kt ni TCP c thit lp.
5-Client gi bn tin HTTP request vi phng thc GET. Ni dung nh sau (v d):
Code:
GET http://192.168.1.10/index.html HTTP/1.0<CRLF>
User-Agent: Chrome/15.0<CRLF>
<CRLF>

6-Webserver tr li bng mt bn tin HTTP response, vi phn Entity-body chnh l ni dung


m HTML ca trang web trn:
Code:
HTTP/1.0 200 Document follows<CRLF>
Server: AVR_Small_Webserver<CRLF>
Content-Type: text/html<CRLF>
Content-Length: 1234<CRLF>
<CRLF>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" dir="ltr" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>AVR web server</title>

</head>
<body style="background: #048C04; color: #FFFFFF">
<br>
<table bgcolor="#489D48" border="0" width="975" cellpadding="0" cellspacing="0"
align="center">
<tbody>
<tr>
<td height="31" align="center">
<div style="font-size:48pt; color:#F4FC8F"><strong>REMOTE CONTROL AVR
WEBSERVER</strong></div>
</td>
</tr>
</tbody>
</table>
<table width="100%" cellpadding="0" cellspacing="0">
<tbody>
<tr>
<td>
<br>
<div align="center">
<div style="background: #ffffff; color: #000000; width:975px; text-align:left">
<div style="padding:0px 15px 0px 15px" align="left">
<br>
<table style="background: #999999; color: #000000; border: 1px solid #6581c1"
cellpadding="6" cellspacing="1" border="0" width="100%" align="center">
<tbody>
<tr style="background: #FFFFFF; color: #545454; border-left: 1px solid #FFFFFF;
border-top: 1px solid #FFFFFF">
<td width="100%">
<div style="font-size:10pt"><strong>DESIGNER: THANH - TAM</strong></div>
</td>
<td nowrap="nowrap" style="padding:0px">
</td>
</tr>
</tbody>
</table>
<br>
<table style="background: #999999; color: #000000; border: 1px solid #6581c1"
cellpadding="6" cellspacing="1" border="0" width="100%" align="center">
<thead>
<tr valign="top">
<td style="background: #FFFFFF; color: #048C04" colspan="3"><strong>Remote
control webserver with ATmega32</a></strong></td>
</tr>
</thead>
<tbody id="collapseobj_vietvbb_stats" style="">
<tr>
<td style="background: #FFFFFF; color: #545454; border-left: 1px solid
#FFFFFF; border-top: 1px solid #FFFFFF">
<table border="1" cellpadding="0" cellspacing="0" width="100%">
<tbody>
<tr style="font-size:12pt">
<td style="padding: 5px 5px 5px 5px;" width="25%">
<div>
<strong>Camera view</strong>
</div>
</td>
<td style="padding: 5px 5px 5px 5px;" width="25%">
<div>
<strong>Devices control</strong>
</div>
</td>
<td style="padding: 5px 5px 5px 5px;" width="50%">

<div>
<strong>Sensors</strong>
</div>
</td>
</tr>
<tr style="font:bold 12pt">
<td style="padding: 5px 5px 5px 5px;" width="25%">
<div id="vietvbb_topstats_s_content" style="display: block;">
<img
src="http://d.f5.photo.zdn.vn/upload/original/2011/06/19/1/24/1308421475585659804_574_0.j
pg" width="320" height="240" />
</div>
</td>
<td style="padding: 5px 5px 5px 5px;" width="25%">
<div>
<form method="POST" action="">
<p align="left"><input type="checkbox" name="RELAY1"
value="ON"%RL1>Relay 01</p>
<p align="left"><input type="checkbox" name="RELAY2"
value="ON"%RL2>Relay 02</p>
<p align="left"><input type="checkbox" name="RELAY3"
value="ON"%RL3>Relay 03</p>
<p align="left"><input type="checkbox" name="RELAY4"
value="ON"%RL4>Relay 04</p>
<p align="left"><input type="submit" value="Submit" name="CTRL"></p>
</form>
</div>
</td>
<td style="padding: 5px 5px 5px 5px;" width="50%">
<div>
<table border="1" width="100%" id="table1">
<tr>
<td>Environment Sensors</td>
<td width="42">Value</td>
<td width="33">Unit</td>
<td width="150">&nbsp;</td>
</tr>
<tr>
<td>Sensor 01</td>
<td width="42">%AD0</td>
<td width="33"><sup>o</sup>C</td>
<td width="150">&nbsp;</td>
</tr>
<tr>
<td>Sensor 02</td>
<td width="42">%AD1</td>
<td width="33"><sup>o</sup>C</td>
<td width="150">&nbsp;</td>
</tr>
</table>
</div>
</td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
<br><br><br>
<div align="center">Timezone: GMT+7. Current time <span>%TI</span>.</div>
<br>
</div>

</div>
</div>
<form action="footer" method="get">
<br>
<div align="center">
<div align="center">Designed by thanh - tam</div>
</div>
</form>
</td>
</tr>
</tbody>
</table>
</div>
</body>
</html>

7-Webserver ng kt ni TCP.
8-Trnh duyt trn client phn tch m HTML, hin th ni dung trang web, phn hnh nh (<img
src="http://d.f5.photo.zdn.vn/upload/original/2011/06/19/1/24/1308421475585659804_574_
0.jpg" width="320" height="240" />) vn cha c (cha trng).
9-Client cn c vo URL ca hnh nh
(http://d.f5.photo.zdn.vn/upload/original/2011/06/19/1/24/1308421475585659804_574_0.jpg
) thit lp 1 kt ni TCP mi, ti hnh nh trn v v hin th ln.
Mi ngi c g thc mc c hi nh. i ch c l gii thch khng c r rng lm.
By gi bt u phn Coding:
Tng t, ta to ra cc file source v header trong project:
File "http.c"
Code:
//---------------------------------------------------------------------------// Writen by NTTam - PTITHCM
//---------------------------------------------------------------------------#include "packet.h"
#include "ethernet.h"
#include "http.h"
#include "webpage.h"
#include "uart.h"
#include "ntAVRnet.h"

File "http.h"
Code:
//---------------------------------------------------------------------------// Writen by NTTam - PTITHCM
//---------------------------------------------------------------------------#ifndef HTTP_H
#define HTTP_H
//---------------------------------------------------------------------------#endif //HTTP_H

Ta to thm 1 file header c tn "webpage.h" cha ni dung trang web


Code:

//---------------------------------------------------------------------------// Writen by NTTam - PTITHCM


//---------------------------------------------------------------------------#ifndef WEBPAGE_H
#define WEBPAGE_H
//---------------------------------------------------------------------------#endif //WEBPAGE_H

By gi ta bt u vi file "webpage.h" trc, chuyn ni dung file HTML m ta son tho


phn trc vo trong ROM ca AVR:
Ta khai bo trong "webpage.h" mt chui k t lu trong b nh ROM:
Code:
//---------------------------------------------------------------------------// Writen by NTTam - PTITHCM
//---------------------------------------------------------------------------#ifndef WEBPAGE_H
#define WEBPAGE_H
//
#include <avr/pgmspace.h>
PROGMEM char Page1[] = {};
//---------------------------------------------------------------------------#endif //WEBPAGE_H

Tip theo ta chuyn ni dung file html trn vo chui trn. Lm theo cc bc sau:
1-M notepad, copy tt c m html trong file "web.html" chun b vo. C th b cc k t
<space> u dng cho tit kim b nh.
2-Bm Ctrl-H m cng c find & replace: tm k t du nhy kp: " v thay tt c bng: \".
L do ca thao tc ny l trong ngn ng C, du nhy kp s kt thc 1 chui, do nu trong
chui ca ta c du nhy ny th phi thay bng \" .
Kt qu ti y ta s c ni dung trn notepad nh sau:
Code:
<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0
Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">
<html xmlns=\"http://www.w3.org/1999/xhtml\" dir=\"ltr\" lang=\"en\">
<head>
<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">
<title>AVR web server</title>
</head>
<body style=\"background: #048C04; color: #FFFFFF\">
<br>
<table bgcolor=\"#489D48\" border=\"0\" width=\"975\" cellpadding=\"0\" cellspacing=\"0\"
align=\"center\">
<tbody>
<tr>
<td height=\"31\" align=\"center\">
<div style=\"font-size:48pt; color:#F4FC8F\"><strong>REMOTE CONTROL AVR
WEBSERVER</strong></div>
</td>
</tr>
</tbody>
</table>
<table width=\"100%\" cellpadding=\"0\" cellspacing=\"0\">

<tbody>
<tr>
<td>
<br>
<div align=\"center\">
<div style=\"background: #ffffff; color: #000000; width:975px; text-align:left\">
<div style=\"padding:0px 15px 0px 15px\" align=\"left\">
<br>
<table style=\"background: #999999; color: #000000; border: 1px solid #6581c1\"
cellpadding=\"6\" cellspacing=\"1\" border=\"0\" width=\"100%\" align=\"center\">
<tbody>
<tr style=\"background: #FFFFFF; color: #545454; border-left: 1px solid #FFFFFF; bordertop: 1px solid #FFFFFF\">
<td width=\"100%\">
<div style=\"font-size:10pt\"><strong>DESIGNER: THANH - TAM</strong></div>
</td>
<td nowrap=\"nowrap\" style=\"padding:0px\">
</td>
</tr>
</tbody>
</table>
<br>
<table style=\"background: #999999; color: #000000; border: 1px solid #6581c1\"
cellpadding=\"6\" cellspacing=\"1\" border=\"0\" width=\"100%\" align=\"center\">
<thead>
<tr valign=\"top\">
<td style=\"background: #FFFFFF; color: #048C04\" colspan=\"3\"><strong>Remote control
webserver with ATmega32</a></strong></td>
</tr>
</thead>
<tbody id=\"collapseobj_vietvbb_stats\" style=\"\">
<tr>
<td style=\"background: #FFFFFF; color: #545454; border-left: 1px solid #FFFFFF; bordertop: 1px solid #FFFFFF\">
<table border=\"1\" cellpadding=\"0\" cellspacing=\"0\" width=\"100%\">
<tbody>
<tr style=\"font-size:12pt\">
<td style=\"padding: 5px 5px 5px 5px;\" width=\"25%\">
<div>
<strong>Camera view</strong>
</div>
</td>
<td style=\"padding: 5px 5px 5px 5px;\" width=\"25%\">
<div>
<strong>Devices control</strong>
</div>
</td>
<td style=\"padding: 5px 5px 5px 5px;\" width=\"50%\">
<div>
<strong>Sensors</strong>
</div>
</td>
</tr>
<tr style=\"font:bold 12pt\">
<td style=\"padding: 5px 5px 5px 5px;\" width=\"25%\">
<div id=\"vietvbb_topstats_s_content\" style=\"display: block;\">
<img
src=\"http://d.f5.photo.zdn.vn/upload/original/2011/06/19/1/24/1308421475585659804_574_0.
jpg\" width=\"320\" height=\"240\" />
</div>
</td>

<td style=\"padding: 5px 5px 5px 5px;\" width=\"25%\">


<div>
<form method=\"POST\" action=\"\">
<p align=\"left\"><input type=\"checkbox\" name=\"RELAY1\" value=\"ON\"%RL1>Relay
<p align=\"left\"><input type=\"checkbox\" name=\"RELAY2\" value=\"ON\"%RL2>Relay
<p align=\"left\"><input type=\"checkbox\" name=\"RELAY3\" value=\"ON\"%RL3>Relay
<p align=\"left\"><input type=\"checkbox\" name=\"RELAY4\" value=\"ON\"%RL4>Relay
<p align=\"left\"><input type=\"submit\" value=\"Submit\" name=\"CTRL\"></p>
</form>
</div>
</td>
<td style=\"padding: 5px 5px 5px 5px;\" width=\"50%\">
<div>
<table border=\"1\" width=\"100%\" id=\"table1\">
<tr>
<td>Environment Sensors</td>
<td width=\"42\">Value</td>
<td width=\"33\">Unit</td>
<td width=\"150\">&nbsp;</td>
</tr>
<tr>
<td>Sensor 01</td>
<td width=\"42\">%AD0</td>
<td width=\"33\"><sup>o</sup>C</td>
<td width=\"150\">&nbsp;</td>
</tr>
<tr>
<td>Sensor 02</td>
<td width=\"42\">%AD1</td>
<td width=\"33\"><sup>o</sup>C</td>
<td width=\"150\">&nbsp;</td>
</tr>
</table>
</div>
</td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
<br><br><br>
<div align=\"center\">Timezone: GMT+7. Current time <span>%TI</span>.</div>
<br>
</div>
</div>
</div>
<form action=\"footer\" method=\"get\">
<br>
<div align=\"center\">
<div align=\"center\">Designed by thanh - tam</div>
</div>
</form>
</td>
</tr>
</tbody>
</table>
</div>
</body>
</html>

3-Ta thm du nhy kp vo u v cui mi dng.

01</p>
02</p>
03</p>
04</p>

4-Copy tt c, b vo gia 2 du ngoc nhn trong khai bo PROGMEM char Page1[] = {};
Kt qu ta s c file "webpage.h" nh vy:
Code:
//---------------------------------------------------------------------------// Writen by NTTam - PTITHCM
//---------------------------------------------------------------------------#ifndef WEBPAGE_H
#define WEBPAGE_H
//
#include <avr/pgmspace.h>
PROGMEM char Page1[] = {"<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\"
\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">"
"<html xmlns=\"http://www.w3.org/1999/xhtml\" dir=\"ltr\" lang=\"en\">"
"<head>"
"<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">"
"<title>AVR web server</title>"
"</head>"
"<body style=\"background: #048C04; color: #FFFFFF\">"
"<br>"
"<table bgcolor=\"#489D48\" border=\"0\" width=\"975\" cellpadding=\"0\"
cellspacing=\"0\" align=\"center\">"
"<tbody>"
"<tr>"
"<td height=\"31\" align=\"center\">"
"<div style=\"font-size:48pt; color:#F4FC8F\"><strong>REMOTE CONTROL AVR
WEBSERVER</strong></div>"
"</td>"
"</tr>"
"</tbody>"
"</table>"
"<table width=\"100%\" cellpadding=\"0\" cellspacing=\"0\">"
"<tbody>"
"<tr>"
"<td>"
"<br>"
"<div align=\"center\">"
"<div style=\"background: #ffffff; color: #000000; width:975px; text-align:left\">"
"<div style=\"padding:0px 15px 0px 15px\" align=\"left\">"
"<br>"
"<table style=\"background: #999999; color: #000000; border: 1px solid #6581c1\"
cellpadding=\"6\" cellspacing=\"1\" border=\"0\" width=\"100%\" align=\"center\">"
"<tbody>"
"<tr style=\"background: #FFFFFF; color: #545454; border-left: 1px solid #FFFFFF; bordertop: 1px solid #FFFFFF\">"
"<td width=\"100%\">"
"<div style=\"font-size:10pt\"><strong>DESIGNER: THANH - TAM</strong></div>"
"</td>"
"<td nowrap=\"nowrap\" style=\"padding:0px\">"
"</td>"
"</tr>"
"</tbody>"
"</table>"
"<br>"
"<table style=\"background: #999999; color: #000000; border: 1px solid #6581c1\"
cellpadding=\"6\" cellspacing=\"1\" border=\"0\" width=\"100%\" align=\"center\">"
"<thead>"
"<tr valign=\"top\">"
"<td style=\"background: #FFFFFF; color: #048C04\" colspan=\"3\"><strong>Remote control
webserver with ATmega32</a></strong></td>"
"</tr>"
"</thead>"
"<tbody id=\"collapseobj_vietvbb_stats\" style=\"\">"

"<tr>"
"<td style=\"background: #FFFFFF; color: #545454; border-left: 1px solid #FFFFFF; bordertop: 1px solid #FFFFFF\">"
"<table border=\"1\" cellpadding=\"0\" cellspacing=\"0\" width=\"100%\">"
"<tbody>"
"<tr style=\"font-size:12pt\">"
"<td style=\"padding: 5px 5px 5px 5px;\" width=\"25%\">"
"<div>"
"<strong>Camera view</strong>"
"</div>"
"</td>"
"<td style=\"padding: 5px 5px 5px 5px;\" width=\"25%\">"
"<div>"
"<strong>Devices control</strong>"
"</div>"
"</td>"
"<td style=\"padding: 5px 5px 5px 5px;\" width=\"50%\">"
"<div>"
"<strong>Sensors</strong>"
"</div>"
"</td>"
"</tr>"
"<tr style=\"font:bold 12pt\">"
"<td style=\"padding: 5px 5px 5px 5px;\" width=\"25%\">"
"<div id=\"vietvbb_topstats_s_content\" style=\"display: block;\">"
"<img
src=\"http://d.f5.photo.zdn.vn/upload/original/2011/06/19/1/24/1308421475585659804_574_0.
jpg\" width=\"320\" height=\"240\" />"
"</div>"
"</td>"
"<td style=\"padding: 5px 5px 5px 5px;\" width=\"25%\">"
"<div>"
"<form method=\"POST\" action=\"\">"
"<p align=\"left\"><input type=\"checkbox\" name=\"RELAY1\" value=\"ON\"%RL1>Relay
01</p>"
"<p align=\"left\"><input type=\"checkbox\" name=\"RELAY2\" value=\"ON\"%RL2>Relay
02</p>"
"<p align=\"left\"><input type=\"checkbox\" name=\"RELAY3\" value=\"ON\"%RL3>Relay
03</p>"
"<p align=\"left\"><input type=\"checkbox\" name=\"RELAY4\" value=\"ON\"%RL4>Relay
04</p>"
"<p align=\"left\"><input type=\"submit\" value=\"Submit\" name=\"CTRL\"></p>"
"</form>"
"</div>"
"</td>"
"<td style=\"padding: 5px 5px 5px 5px;\" width=\"50%\">"
"<div>"
"<table border=\"1\" width=\"100%\" id=\"table1\">"
"<tr>"
"<td>Environment Sensors</td>"
"<td width=\"42\">Value</td>"
"<td width=\"33\">Unit</td>"
"<td width=\"150\">&nbsp;</td>"
"</tr>"
"<tr>"
"<td>Sensor 01</td>"
"<td width=\"42\">%AD0</td>"
"<td width=\"33\"><sup>o</sup>C</td>"
"<td width=\"150\">&nbsp;</td>"
"</tr>"
"<tr>"

"<td>Sensor 02</td>"
"<td width=\"42\">%AD1</td>"
"<td width=\"33\"><sup>o</sup>C</td>"
"<td width=\"150\">&nbsp;</td>"
"</tr>"
"</table>"
"</div>"
"</td>"
"</tr>"
"</tbody>"
"</table>"
"</td>"
"</tr>"
"</tbody>"
"</table>"
"<br><br><br>"
"<div align=\"center\">Timezone: GMT+7. Current time <span>%TI</span>.</div>"
"<br>"
"</div>"
"</div>"
"</div>"
"<form action=\"footer\" method=\"get\">"
"<br>"
"<div align=\"center\">"
"<div align=\"center\">Designed by thanh - tam</div>"
"</div>"
"</form>"
"</td>"
"</tr>"
"</tbody>"
"</table>"
"</div>"
"</body>"
"</html>"};
//---------------------------------------------------------------------------#endif //WEBPAGE_H

Ai m li th copy y chang file ny, kt qu l trang web s c hnh ch cn nh mnh.


Tip theo, ta quay li file "http.h". Thm cc define cho cc method ca request:
Code:
//
#define
#define
#define
#define
//
#define
#define
#define
//

HTTP_REQUEST_GET
HTTP_REQUEST_POST
HTTP_REQUEST_HEAD
HTTP_REQUEST_UNKNOWN

1//"GET"
2//"POST"
3//"HEAD"
4//Request quai qui gi do ma ta khong biet

HTTP_REQUEST_GET_STR
HTTP_REQUEST_POST_STR
HTTP_REQUEST_HEAD_STR

"GET"
"POST"
"HEAD"

Sau l khai bo struct tng ng vi bn tin request:


Code:
//
struct httpRequest{
unsigned char
unsigned char
unsigned char
unsigned char
unsigned char

method;
*requestURI;
*version;
*header;
*body;

//end
//end
//end
//end
//

with
with
with
with

space
space
\n\r
\n\r\n\r

unsigned int bodyLen;


};

y cc bn lu l khc vi cc header khc, ta dng ch yu bin con tr tr cc field


trong bn tin request, v kch thc cc field trong bn tin khng c nh, nn v tr bt u
field cng khng c nh. Ta dng bin co tr tr n u mi field, cn kt thc field th
ng nhin l trc khi bt u filed tip theo, tr field cui cng l body, ta cho n 1 bin
chiu di.
Webserver phi c kh nng thit lp ng thi nhiu phin kt ni, do ta khai bo 1 struct
na lu thng tin v mi phin kt ni HTTP:
Code:
struct httpSession{
unsigned char status;
const prog_char *headerPointer;
const prog_char *bodyPointer;
chuong trinh
unsigned char *authStr;
unsigned char auth;
struct httpRequest rqst;
struct tcpSession *pTCPSession;
};

//Trang thai hien tai


//Con tro den header trong bo nho chuong trinh
//Con tro den du lieu can gui trong bo nho
//Con tro den chuoi xac thuc
//Xac thuc
//Request tuong ung

Trong struct trn ta c dng t kha prog_char ( ch b nh chng trnh: ROM) nn cc bn


nh include file "pgmspace.h" vo (u file) nu khng s c bo li:
Code:
#include <avr/pgmspace.h>

Cui cng l define cc trng thi ca 1 phin HTTP v s phin ti a c th thit lp ng


thi:
Code:
//
#define
#define
#define
#define
#define
//
#define
//

HTTP_STATUS_IDLE
HTTP_STATUS_GOT_REQUEST
HTTP_STATUS_HEADER_SENT
HTTP_STATUS_HEADER_RECEIVED
HTTP_STATUS_FINISH

0
1
2
3

MAX_HTTP_SESSION

Ti lt file source "http.c"


u tin ta khai bo mt s bn tin response chun webserver s dng:
Bn tin response cho mt request GET/POST hp l, km theo s l ni dung trang web:
Code:
prog_char http_pageheader_ok[]={

"HTTP/1.0 200 Document follows\r\n"


"Server:

AVR_Small_Webserver\r\n"
"Content-Type:
text/html\r\n\r\n"};

Trn y l Status-line v Response Header, Entity Header ca bn tin response, phn Entitybody chnh l ni dung webpage m ta chun b trong file "webpage.h"

Bn tin response yu cu xc thc. Tt nhin trang web remote control ca chng ta phi c
xc thc username/password ri, chc cc bn khng mun ai cng c th truy cp vo bt tt
thit b lung tung ch.
Code:
prog_char http_pageheader_unauth[]={

"HTTP/1.0 401 Unauthorized\r\n"


"Server:

AVR_Small_Webserver\r\n"
"WWW-Authenticate:
Basic realm=\"NeedPassword\""
"\r\nContent-Type:
text/html\r\n\r\n"};

Bn tin bo vic xc thc tht bi:


Code:
prog_char http_pageheader_auth_error[] = {"401 Unauthorized%END"};

Bn tin bo li request mt i tng khng c:


Code:
prog_char http_error_notimp[]={

"HTTP/1.1 501 Not Implemented\r\n"


"Server:

AVR_Small_Webserver\r\n"
"WWW-Authenticate:
Basic realm=\"My AVR web server\""
"\r\nContent-Type:
text/html\r\n\r\n"};

Khai bo 1 array cc bin struct cha thng tin v cc phin HTTP:


Code:
struct httpSession

httpSessionTable[MAX_HTTP_SESSION];

Khai bo 1 char array cha chui xc thc:


Code:
unsigned char http_auth_password[20];

u tin, ta vit hm tnh m xc thc cho username/password:


Code:
//---------------------------------------------------------------------------PROGMEM char BASE64CODE[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
//
void decode_base64 (unsigned char *str1_in,unsigned char *str2_out)
{
unsigned char *strp;
unsigned char end_byte = 0;
strp = str2_out;
while (*str1_in != 0)
{
*str2_out++= (*str1_in & 0xFC)>>2;
*str2_out = (((*str1_in++)&0x03)<<4);
if (*str1_in==0)
{

str2_out++;
end_byte = 2;
break;
}
else
{
*str2_out++ += ((*str1_in & 0xF0)>>4);
*str2_out = (((*str1_in++)& 0x0F)<<2);
if (*str1_in==0)
{
str2_out++;
end_byte = 1;
break;
}
else
{
*str2_out++
+= ((*str1_in & 0xC0)>>6);
*str2_out++= *str1_in++ & 0x3F;
}
}
}
*str2_out = 0;
while(strp != str2_out)
{
*strp = pgm_read_byte(&BASE64CODE[(*strp) & 0x3F]);
strp++;
}
while (end_byte--)
{
*strp = '=';
strp++;
}
*strp = 0;
}

Hm khi to giao thc HTTP (thc cht l khi to gi tr ban u cho cc bin):
Code:
//---------------------------------------------------------------------------void httpInit()
{
unsigned char i;
decode_base64((unsigned char*)HTTP_AUTH_STRING,http_auth_password);
for(i=0; i < MAX_HTTP_SESSION; i++){
httpSessionTable[i].status = HTTP_STATUS_IDLE;
}
//UpdateCtrlSts(0x00);
}

Ta m file "ntAVRnet.h" khai bo chui xc thc username/password cho trang web ca chng
ta (gi s username l admin, password l 1234):
Code:
#define HTTP_AUTH_STRING "admin:1234"

Tip theo, ta vit hm x l 1 request nhn c. Lc ny, request nhn c qua port TCP 80
ang nm trn buffer, ngay sau TCP Header. Nhim v ca hm ny l xc nh phng thc
(method) ca request, xc nh v tr cc field, v lu nhng thng tin ny vo struct
httpRequest tng ng.
Code:

//---------------------------------------------------------------------------//Ham xu ly mot request cua giao thuc HTTP


void httpGetRequest(unsigned char *buffer,unsigned int bufferLen,struct httpRequest*
rqst)
{
unsigned int i;
if((buffer[0] == 'G')&&(buffer[1] == 'E')&&(buffer[2] == 'T')){
rqst->method = HTTP_REQUEST_GET;
#ifdef HTTP_DEBUG
printf("GET\r\n");
#endif
}else if((buffer[0] == 'P')&&(buffer[1] == 'O')&&(buffer[2] == 'S')&&(buffer[3]
== 'T')){
rqst->method = HTTP_REQUEST_POST;
#ifdef HTTP_DEBUG
printf("POST\r\n");
#endif
}else if((buffer[0] == 'H')&&(buffer[1] == 'E')&&(buffer[2] == 'A')&&(buffer[3]
== 'D')){
rqst->method = HTTP_REQUEST_HEAD;
#ifdef HTTP_DEBUG
printf("HEAD\r\n");
#endif
}else{
rqst->method = HTTP_REQUEST_UNKNOWN;
#ifdef HTTP_DEBUG
printf("UNKNOWN\r\n");
#endif
}
//Bat dau tim URI va HTTP version
i = 0;
while(++i<bufferLen){
if(buffer[i] == ' '){
//khoang trang dau tien
rqst->requestURI = &buffer[i+1];
break;
}
}
while(++i<bufferLen){
if(buffer[i] == ' '){
//khoang trang dau tien
rqst->version = &buffer[i+1];
break;
}
}
//Tim header
while(++i<bufferLen){
if((buffer[i] == 0x0d) && (buffer[i+1] == 0x0a)){ //\n\r dau tien, bat
dau header
rqst->header = &buffer[i+2];
break;
}
}
//Tim ket thuc header
while(++i<bufferLen){
if((buffer[i] == 0x0d) && (buffer[i+1] == 0x0a) && (buffer[i+2] ==
0x0d)){ //\n\r\n\r
i += 4;
break;
}
}
rqst->body = &buffer[i];
rqst->bodyLen = bufferLen - i;
#ifdef HTTP_DEBUG
printf("Buffer Len:%d\r\n",bufferLen);

printf("URI start:%d\r\n",(rqst->requestURI - buffer));


printf("HTTP Version:%d\r\n",(rqst->version - buffer));
printf("Header:%d\n\r",(rqst->header - buffer));
printf("Body:%d\n\r",(unsigned int)(rqst->body - buffer));
printf("Body:%x-%x\n\r",(unsigned int)(rqst->body),(unsigned int)buffer);
printf("Body i:%d\n\r",i);
#endif
}

V hm ly gi tr ca 1 trng HTTP Header:


Code:
//---------------------------------------------------------------------------//Ham lay gia tri mot truong trong HTTP Header,
// tra lai con tro vi tri bat dau value cua truong nay
unsigned char * httpHeaderGetField(const prog_char fieldname[],struct httpRequest *rqst)
{
unsigned char *header;
unsigned int i,j,headerLen;
header = rqst->header;
headerLen = (rqst->header) - (rqst->body) - 4;
i=0;
j=0;
while(i<headerLen){
if(header[i++] != pgm_read_byte(fieldname + j++)){
j = 0;
}
if(pgm_read_byte(fieldname + j) == 0){
return(header+i+2);
}
}
return(0);
}

Tip theo, ta vit 2 hm chnh ca giao thc HTTP: hm gi mt bn tin HTTP i v hm x l 1


request nhn c:
u tin, ta cn 2 hm tm kim chui m ta s s dng trong 2 hm chnh trn:
- Hm tm 1 chui lu trong b nh chng trnh (ROM) trong 1 chui lu trong RAM
Code:
//---------------------------------------------------------------------------unsigned int findstr(const prog_char progstr[],unsigned char* str,unsigned int len)
{
unsigned int i,j;
i=0;
j=0;
while(i<len){
if(str[i++] != pgm_read_byte(progstr + j++)){
j = 0;
}
if(pgm_read_byte(progstr + j) == 0){
return(i-j);
}
}
return(-1);
}

- Hm tm 1 chui lu trong b nh RAM trong 1 chui cng lu trong RAM


Code:

//---------------------------------------------------------------------------unsigned int findstrdatamem(unsigned char* str1,unsigned char* str2,unsigned int len)


{
unsigned int i,j;
i=0;
j=0;
while(i<len){
if(str2[i++] != str1[j++]){
j = 0;
}
if(str1[j] == 0){
return(i-j);
}
if(str2[i] == 0){
return(-1);
}
}
return(-1);
}

V y l hm gi i mt bn tin HTTP:
Code:
//---------------------------------------------------------------------------//Ham gui mot doan du lieu chua trong bo nho chuong trinh ra theo giao thuc HTTP
void
HTTPSend(const prog_char progdata[],unsigned int dataLen,struct tcpSession
*pSession, unsigned char endData)
{
unsigned int i;
unsigned int srcDataIdx = 0;
unsigned char* dataBuffer;
unsigned char Flags;
unsigned char tmpChr;
Flags = TCP_PSH_FLAG;
dataBuffer = ethGetBuffer() + ETH_HEADER_LEN + IP_HEADER_LEN + TCP_HEADER_LEN;
if(dataLen == 0){
Flags |= TCP_ACK_FLAG;
if(endData){
if(srcDataIdx == dataLen){
Flags |= TCP_FIN_FLAG;
pSession->sesState = TCP_STATE_FIN_WAIT1;
}
}
TCPPackedSend(pSession,Flags,0,dataBuffer);
}
while(srcDataIdx < dataLen){
i = 0;
while(i<MAX_SEGMENT_SIZE){
tmpChr = pgm_read_byte(progdata + srcDataIdx++);
dataBuffer[i++] = tmpChr; //Copy data to tcp data buffer
if(srcDataIdx==dataLen){
break;
}
}
Flags |= TCP_ACK_FLAG;
if(endData){
if(srcDataIdx == dataLen){
Flags |= TCP_FIN_FLAG;
pSession->sesState = TCP_STATE_FIN_WAIT1;
}
}
TCPPackedSend(pSession,Flags,i,dataBuffer);
//delay_ms(100);

#ifdef NETSTACK_DEBUG
printf("Sent %d byte\r\n",srcDataIdx);
#endif
}
}

Hm x l 1 request nhn c:
Code:
//---------------------------------------------------------------------------//Ham xu ly mot goi thuoc giao thuc HTP nhan duoc
void httpDataIn(unsigned char *buffer,unsigned int bufferLen,struct tcpSession *pSession)
{
unsigned char i;
unsigned char *tmpstr;
prog_char Auth_str[]="Authorization";
//Tim xem cophien HTTP service da co cho phien TCP nay khong
for(i=0; i < MAX_HTTP_SESSION; i++){
if((httpSessionTable[i].status != HTTP_STATUS_IDLE) &&
(httpSessionTable[i].pTCPSession == pSession))
break;
}
if(i == MAX_HTTP_SESSION){
//Tim 1 phien trong
for(i=0; i < MAX_HTTP_SESSION; i++){
if(httpSessionTable[i].status == HTTP_STATUS_IDLE){
httpSessionTable[i].pTCPSession = pSession;
break;
}
}
}
if(httpSessionTable[i].status == HTTP_STATUS_IDLE){
//Neu day la 1 HTTP request moi
//Kiem tra method cua request
httpGetRequest(buffer,bufferLen,&(httpSessionTable[i].rqst));
if(httpSessionTable[i].rqst.method == HTTP_REQUEST_UNKNOWN){
//Neu request khong biet, thoat tro ve trang thai idle
httpSessionTable[i].status = HTTP_STATUS_IDLE;
return;
}else{
//Set trang thai cua HTTP session thanh HEADER_RECEIVED (da nhan header)
httpSessionTable[i].status = HTTP_STATUS_HEADER_RECEIVED;
}
}
//Neu da nhan header
if(httpSessionTable[i].status == HTTP_STATUS_HEADER_RECEIVED){
//Kiem tra xem da xac thuc hay chua
if(httpSessionTable[i].auth != 1){
tmpstr =
httpHeaderGetField(Auth_str,&(httpSessionTable[i].rqst));
if(findstrdatamem(http_auth_password,tmpstr,httpSessionTable[i].rqst.body-tmpstr)
!= -1){
#ifdef HTTP_DEBUG
printf("Auth OK\n\r");
printfStr(http_auth_password);
printf("Input\n\r");
printfStr(tmpstr);
#endif
httpSessionTable[i].auth = 1;
//Neu xac thuc khong hop le
}else{
#ifdef HTTP_DEBUG

printf("Auth fail\n\r");
printf("Auth string:");
printfStr(http_auth_password);
printf("\n\r");
printf("Received string:");
printfStrLen(tmpstr,0,20);
#endif
HTTPSend(http_pageheader_unauth,sizeof(http_pageheader_unauth)-1,pSession,0);
HTTPSend(http_pageheader_auth_error,sizeof(http_pageheader_auth_error)1,pSession,1);
httpSessionTable[i].status = HTTP_STATUS_IDLE;
return;
}
}
//Process for each method
//If GET method
if(httpSessionTable[i].rqst.method == HTTP_REQUEST_GET){
#ifdef HTTP_DEBUG
printf("GET HEADER:\n\r");
printfStrLen(httpSessionTable[i].rqst.header,0
,(httpSessionTable[i].rqst.body httpSessionTable[i].rqst.header) + httpSessionTable[i].rqst.bodyLen);
#endif
//If GET the main website
if((httpSessionTable[i].rqst.requestURI[0] == '/') &&
(httpSessionTable[i].rqst.requestURI[1] == ' ')){
HTTPSend(http_pageheader_ok,sizeof(http_pageheader_ok)1,pSession,0);
HTTPSend(Page1,sizeof(Page1)-1,pSession,1);
httpSessionTable[i].status = HTTP_STATUS_IDLE;
//If error
}else{
HTTPSend(http_error_notimp,sizeof(http_error_notimp),pSession,1);
httpSessionTable[i].status = HTTP_STATUS_IDLE;
}
return;
//If POST method
}else if(httpSessionTable[i].rqst.method == HTTP_REQUEST_POST){
//Update POST data
if(findstr(PSTR("SUB=Submit"),buffer,bufferLen) != -1){
//Send HTTP data
HTTPSend(http_pageheader_ok,sizeof(http_pageheader_ok)1,pSession,0);
HTTPSend(Page1,sizeof(Page1)-1,pSession,1);
httpSessionTable[i].status = HTTP_STATUS_IDLE;
return;
}else if(findstr(PSTR("APPLY=Apply"),buffer,bufferLen) != -1){
HTTPSend(http_pageheader_ok,sizeof(http_pageheader_ok)1,pSession,0);
HTTPSend(Page1,sizeof(Page1)-1,pSession,1);
httpSessionTable[i].status = HTTP_STATUS_IDLE;
}else{
HTTPSend("",0,pSession,0);
}
}
}
}

Trong cc hm trn ta c gi hm ca giao thc TCP nn cc bn include file "tcp.h" vo u


file nh:

Code:
#include "tcp.h"

V nh thm khai bo cc hm vit vo file header "http.h"


c th bin dch v khi ng webserver, ta cn sa 1 t trong chng trnh chnh.
M file "ntAVRnet.h", thm vo cc include 2 file "tcp.h" v "http.h":
Code:
#include "tcp.h"
#include "http.h"

Thm vo hm netInit lnh khi ng giao thc TCP v HTTP:


Code:
TCPInit();
httpInit();

Thm vo hm main lnh khi ng phin TCP port 80 trng thi listen cho dch v HTTP
(trc vng lp while(1)):
Code:
TCPCreateSession(80,httpDataIn);

By gi cc bn c th bin dch v chy th, c th truy cp web nhng cha c chc nng
gim st v iu khin t xa qua webserver, i bi tip theo nh

Nguyn vn bi dinh_dong

Thy cho em hi cu ny vi:


Hm ny trong file udp.c: void udpSend(unsigned long dstIp, unsigned int dstPort, unsigned
int len, unsigned char* udpData)
Cn cu lnh gi hm ny trong file dhcp.c:udpSend(DhcpServerIP, DHCP_UDP_SERVER_PORT,
DHCP_UDP_CLIENT_PORT, DHCP_HEADER_LEN+3+6+6+1, (unsigned char*)packet);
agrument (s bin gi hm khng nh nhau)ca cu lnh gi hm ko ng, e ko bit sa th
no? Mong thy gip!
ci ny, thy Tm ni r l sa li ri m. bn tm k li xem, c th nh sau:
void udpSend(unsigned long dstIp, unsigned int dstPort, unsigned int srcPort, unsigned int len,
unsigned char* udpData)
{
struct ntUDPHeader* udpHeader;
udpHeader = (struct ntUDPHeader*)(udpData - UDP_HEADER_LEN);
len += UDP_HEADER_LEN;
udpHeader->desPort = HTONS(dstPort);
udpHeader->srcPort = HTONS(srcPort);
udpHeader->Len = HTONS(len);
udpHeader->Checksum = 0;
ipSend(dstIp, IP_PROTO_UDP, len, (unsigned char*)udpHeader);
}

Lu nay bn cng vic gia nh v c quan nhiu qu nn b ri Thread, nay rnh ri cht li
tr li mi ngi tip nh:
1-c, cch thc hin cn ty bn iu xung bng Timer hay vng lp,...
2-Thut ton iu khin relay hay led g nh sau:
Khi my tnh ti ni dung trang web v trnh duyt, trn trang web s c 1 on code HTML
m t mt nt bm hoc 1 nt check, v d:
Code:
<form method="post" action="">
<p align="left"><input type="checkbox" name="OUT" value="C" checked>Aqua Lamp</p>
<p align="left"><input type="checkbox" name="OUT" value="B">Filter</p>
<p align="left"><input type="checkbox" name="OUT" value="A">Chiller</p>
<p align="left"><input type="checkbox" name="OUT" value="D">Cooler Fan</p>
<p align="left"><input type="submit" value="Submit" name="SUB"></p>
</form>

on code trn s to ra 1 form gm c 4 nt check (type="checkbox") v text hin th bn


cnh tng ng l:Aqua Lamp,Filter,Chiller,Cooler Fan. Dng no c t kha checked l check
box ang c chn.

on code trn cng qui nh cc input m ngi dng nhp vo (gi tr check) s c gi

tr li cho webserver bng phng thc http post (method="post").


Sau khi ta nh du vo cc v nhn nt Submit, my tnh s gi n webserver 1 bn tin
http post vi gi tr ca cc check c cha trong phn body ca bn tin post (xem li cu
trc bn tin http post phn trc.
Nh vy trong chng trinh trn AVR, on code x l bn tin http nhn c (hm
httpDataIn ta cn x l bn tin ny. C th trong on code cho trng hp bn tin l http post
(else if(httpSessionTable[i].rqst.method == HTTP_REQUEST_POST)), ta cn c ni dung bn
tin, tm kim cc gi tr: OUT=A (Relay 1); OUT=B (Relay 2); OUT=C (Relay 3); OUT=D (Relay
4); (OUT l trng name ca code HTML ca check, A,B,C,D l trng value). Khi thy gi tr
tng ng th ta ng ngt re lay tng ng thi.

1.

Nguyn vn bi wind-gon

Mng qu anh tr li. Cng vic ca anh th no,c bn rn,p lc nh trc m anh ni
khng?
Ah,Anh c th ni r hn phn ny gip em vi???Em loay hoay mi khng sa c.
Hin ti em lm xong y phn mch iu khin c cc thit b qut,n(1 chiu +
xoay chiu),cm bin chng trm,v lp trnh hn thi gian.
Cng vic vn vy, c khi cn bn rn hn, chn qu, lm hoi khng ht, vic u c n n
ko ti.
Ni chung cch lm nh sau:
I-Cp nht trng thi cc relay v gi tr sensor cho Web:
Mi ngi l trong ni dung trang web, ch gi tr ca relay v sensor mnh 1
keyword tng ng, l: %RL1, %RL2, %RL3, %RL4 v %AD0, %AD1.
Ch ny chnh l ch cn thay th cc gi tr tng ng trc khi gi ni dung xung cho client.
Vy trong hm HTTPSend() (hm gi ni dung web xung client) cn sa li cp nhp cc
thng tin ny. V d nh sau:
Code:
void
HTTPSend(const prog_char progdata[],unsigned int dataLen,struct tcpSession
*pSession, unsigned char endData)
{
unsigned int i;
unsigned int srcDataIdx = 0;
unsigned char* dataBuffer;
unsigned char Flags;
unsigned char tmpChr,tmpVar;
unsigned char* tmpStr;
Flags = TCP_PSH_FLAG;
dataBuffer = ethGetBuffer() + ETH_HEADER_LEN + IP_HEADER_LEN + TCP_HEADER_LEN;
if(dataLen == 0){

Flags |= TCP_ACK_FLAG;
if(endData){
if(srcDataIdx == dataLen){
Flags |= TCP_FIN_FLAG;
pSession->sesState = TCP_STATE_FIN_WAIT1;
}
}
TCPPackedSend(pSession,Flags,0,dataBuffer);
}
while(srcDataIdx < dataLen){
i = 0;
while(i<MAX_SEGMENT_SIZE){
tmpChr = pgm_read_byte(progdata + srcDataIdx++);
if(tmpChr == '%'){
//Truong hop ung voi dieu khien relay
("%RLx) hay gia tri AD ("%ADx")
if( (i + 9) > MAX_SEGMENT_SIZE){ //Neu khong con du
cho trong tren buffer
srcDataIdx--;
break;
}
//Tiep tuc neu du cho trong tren buffer
tmpVar = pgm_read_byte(progdata + srcDataIdx + 3) 0x30;
if((pgm_read_byte(progdata + srcDataIdx) == 'R') &&
(pgm_read_byte(progdata + srcDataIdx + 1) == 'L')){
if(GetRelayState(tmpVar)){//checked
dataBuffer[i++] = ' ';dataBuffer[i++]
= 'c';dataBuffer[i++] = 'h';dataBuffer[i++] = 'e';
dataBuffer[i++] = 'c';dataBuffer[i++]
= 'k';dataBuffer[i++] = 'e';dataBuffer[i++] = 'd';
}
srcDataIdx += 4;
}else if((pgm_read_byte(progdata + srcDataIdx) == 'A')
&& (pgm_read_byte(progdata + srcDataIdx + 1) == 'D')){
tmpStr = (unsigned
char*)uInt2StrLen(LM35_TYP_DECODE(GetADC(tmpVar)),3);//(unsigned
char*)uByte2Str(GetAD(tmpChr));
tmpVar = 0;
dataBuffer[i++] = tmpStr[tmpVar++];
dataBuffer[i++] = tmpStr[tmpVar++];
dataBuffer[i++] = '.';
dataBuffer[i++] = tmpStr[tmpVar++];
//while(tmpStr[tmpChr] != 0){
//
dataBuffer[i++] = tmpStr[tmpChr++];
//}
srcDataIdx += 4;
}else{// Neu truong hop khac:
dataBuffer[i++] = tmpChr;
}
}
else{
dataBuffer[i++] = tmpChr; //Copy data to tcp data buffer
}
if(srcDataIdx==dataLen){
break;
}
}
Flags |= TCP_ACK_FLAG;
if(endData){
if(srcDataIdx == dataLen){
Flags |= TCP_FIN_FLAG;
pSession->sesState = TCP_STATE_FIN_WAIT1;
}
}

TCPPackedSend(pSession,Flags,i,dataBuffer);
//delay_ms(100);
#ifdef NETSTACK_DEBUG
printf("Sent %d byte\r\n",srcDataIdx);
#endif
}
}
//--------------------------------------------------------------------------------------

Cc bn thy kh n gin, khi tm thy k t %, nu tip theo l RL1 (%RL1) th ta thay trng
thi ca Relay 1 vo: nu Relay 1 ang ng th gi tr l "checked", nu Relay 1 ang nh,
th trng (hay "unchecked").
Tng t, nu k t tip theo l AD0 (%AD0) th ta thay gi tr tng ng c t ADC vo.
Ch khi thay cc gi tr tng ng ta phi tng bin m (srcDataIdx) ln tng ng vi
chiu di m ta thm vo.
o

Chia s

mhl167, ga_kon, chikichita v 1 ngi na cm n ni dung ny.


Reply With Quote

2.

20-07-12 13:47#420

nttam79

Thnh vin tch cc


Tham gia
Feb 2009
Bi vit
160
Mentioned
0 Post(s)
Tagged
0 Thread(s)

II-iu khin relay khi nhn c HTTP post (ngi dng nhn nt Submit trn trang web):
Ci ny ta phi sa trong hm HTTPDataIn(), phn x l bn tin HTTP POST
V d:
Code:
//-------------------------------------------------------------------------------------//Ham xu ly mot goi thuoc giao thuc HTP nhan duoc
void httpDataIn(unsigned char *buffer,unsigned int bufferLen,struct tcpSession *pSession)
{
unsigned char i;
unsigned char *tmpstr;

unsigned char tmpRelaySts;


//struct httpRequest rqst;
//Tim xem cophien HTTP service da co cho phien TCP nay khong
for(i=0; i < MAX_HTTP_SESSION; i++){
if((httpSessionTable[i].status != HTTP_STATUS_IDLE) &&
(httpSessionTable[i].pTCPSession == pSession))
break;
}
if(i == MAX_HTTP_SESSION){
//Tim 1 phien trong
for(i=0; i < MAX_HTTP_SESSION; i++){
if(httpSessionTable[i].status == HTTP_STATUS_IDLE){
httpSessionTable[i].pTCPSession = pSession;
break;
}
}
}
if(httpSessionTable[i].status == HTTP_STATUS_IDLE){
//If this is a new HTTP request
//Check for request method
httpGetRequest(buffer,bufferLen,&(httpSessionTable[i].rqst));
//TCPPackedSend(pSession,(TCP_ACK_FLAG),0,buffer);
if(httpSessionTable[i].rqst.method == HTTP_REQUEST_UNKNOWN){
//if invalid request, just cancel
httpSessionTable[i].status = HTTP_STATUS_IDLE;
return;
}else{
//Set HTTP session to HEADER_RECEIVED (for next process)
httpSessionTable[i].status = HTTP_STATUS_HEADER_RECEIVED;
}
}
//If got header
if(httpSessionTable[i].status == HTTP_STATUS_HEADER_RECEIVED){
//Check for auth string
if(httpSessionTable[i].auth != 1){
tmpstr =
httpHeaderGetField(Auth_prog,&(httpSessionTable[i].rqst));
if(findstrdatamem(http_auth_password,tmpstr,httpSessionTable[i].rqst.body-tmpstr)
!= -1){
#ifdef HTTP_DEBUG
printf("Auth OK\n\r");
printfStr(http_auth_password);
printf("Input\n\r");
printfStr(tmpstr);
#endif
httpSessionTable[i].auth = 1;
//If not valid auth
}else{
#ifdef HTTP_DEBUG
printf("Auth fail\n\r");
printf("Auth string:");
printfStr(http_auth_password);
printf("\n\r");
printf("Received string:");
printfStrLen(tmpstr,0,20);
#endif
HTTPSend(http_header3,sizeof(http_header3)1,pSession,0);
HTTPSend(Page0,sizeof(Page0)-1,pSession,1);
httpSessionTable[i].status = HTTP_STATUS_IDLE;
return;
}
}

//Process for each method


//If GET method
if(httpSessionTable[i].rqst.method == HTTP_REQUEST_GET){
#ifdef HTTP_DEBUG
printf("GET HEADER:\n\r");
printfStrLen(httpSessionTable[i].rqst.header,0
,(httpSessionTable[i].rqst.body httpSessionTable[i].rqst.header) + httpSessionTable[i].rqst.bodyLen);
#endif
//If GET the main website
if((httpSessionTable[i].rqst.requestURI[0] == '/') &&
(httpSessionTable[i].rqst.requestURI[1] == ' ')){
HTTPSend(http_header1,sizeof(http_header1)1,pSession,0);
HTTPSend(Page1,sizeof(Page1)-1,pSession,1);
httpSessionTable[i].status = HTTP_STATUS_IDLE;
//If error
}else{
HTTPSend(http_error_notimp,sizeof(http_error_notimp),pSession,1);
httpSessionTable[i].status = HTTP_STATUS_IDLE;
}
return;
//If POST method
}else if(httpSessionTable[i].rqst.method == HTTP_REQUEST_POST){
//Update POS data
if(findstr(PSTR("SUB=Submit"),buffer,bufferLen) != -1){
tmpRelaySts = 0x00;
if((findstr(PSTR("RELAY1=ON"),buffer,bufferLen)) != -1)
{
//SetRelayState(1,1);
tmpRelaySts += 1;
#ifdef HTTP_DEBUG
printf("Relay 1 on\r\n");
#endif
}else{
//SetRelayState(1,0);
//tmpRelaySts += 2;
#ifdef HTTP_DEBUG
printf("Relay 1 off\r\n");
#endif
}
if((findstr(PSTR("RELAY2=ON"),buffer,bufferLen)) != -1)
{
//SetRelayState(2,1);
tmpRelaySts += 2;
#ifdef HTTP_DEBUG
printf("Relay 2 on\r\n");
#endif
}else{
//SetRelayState(2,0);
//tmpRelaySts += 8;
#ifdef HTTP_DEBUG
printf("Relay 2 off\r\n");
#endif
}
if((findstr(PSTR("RELAY3=ON"),buffer,bufferLen)) != -1)
{
//SetRelayState(3,1);
tmpRelaySts += 4;
#ifdef HTTP_DEBUG
printf("Relay 3 on\r\n");
#endif
}else{

//SetRelayState(3,0);
#ifdef HTTP_DEBUG
printf("Relay 3 off\r\n");
#endif
}
if((findstr(PSTR("RELAY4=ON"),buffer,bufferLen)) != -1)
{
//SetRelayState(4,1);
tmpRelaySts += 8;
#ifdef HTTP_DEBUG
printf("Relay 4 on\r\n");
#endif
}else{
//SetRelayState(4,0);
#ifdef HTTP_DEBUG
printf("Relay 4 off\r\n");
#endif
}
UpdateCtrlSts(tmpRelaySts);
//Send HTTP data
HTTPSend(http_header1,sizeof(http_header1)1,pSession,0);
HTTPSend(Page1,sizeof(Page1)-1,pSession,1);
httpSessionTable[i].status = HTTP_STATUS_IDLE;
return;
}else if(findstr(PSTR("APPLY=Apply"),buffer,bufferLen) != -1){
HTTPSend(http_header1,sizeof(http_header1)1,pSession,0);
HTTPSend(Page1,sizeof(Page1)-1,pSession,1);
httpSessionTable[i].status = HTTP_STATUS_IDLE;
}else{
HTTPSend("",0,pSession,0);
}
}
}
}
//--------------------------------------------------------------------------------------

Gii thch:
- Khin ngi dng nhn Submit, client s gi 1 bn tin HTTPPost, request chnh trang web ,
nhng trong mesage body c cha thng tin ly t form trn trang web (trng thi cc n
check m ngi dng thay i).
- V d, trn trang web (trong webpage.h) ta khai bo cc check nh sau:
<p align="left"><input type="checkbox" name="RELAY1" value="ON"%RL1>Relay 01</p>
<p align="left"><input type="checkbox" name="RELAY2" value="ON"%RL2>Relay 02</p>
<p align="left"><input type="checkbox" name="RELAY3" value="ON"%RL3>Relay 03</p>
<p align="left"><input type="checkbox" name="RELAY4" value="ON"%RL4>Relay 04</p>
i vi relay 1, khai bo nh vy tc l tn i tng l RELAY1 (name="RELAY1"), gi tr nhn
c khi n c check l ON (value="ON")
Nh vy gi s cc check box 1 v 3 c check, 2 v 4 b trng, th khi nhn Submit, thng
tin sau s c gi i:
RELAY1=ON
RELAY3=ON
Cn iu khin relay th no l do cc bn thi. trong v d trn mnh lu trng thi cc relay
trong bin tmpRelaySts, sau mi gi hm UpdateCtrlSts(tmpRelaySts) thc thi cc trng
thi .
Chc cc bn thnh cng. Xin li v mi ngi i qu lu.

You might also like