Professional Documents
Culture Documents
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
Set thuc tnh cho project v chn CPU, chn tn s thch anh:
Code:
//---------------------------------------------------------------------------// Writen by NTTam - PTITHCM
//---------------------------------------------------------------------------#include <avr/io.h>
//---------------------------------------------------------------------------int
{
main()
return(0);
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
#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:
0x00
0x3A
0x40
0x7A
0x80
0xA0
0xFF
TXSTART_INIT
TXSTOP_INIT
RXSTART_INIT
RXSTOP_INIT
0x0000
0x05FF
0x0600
0x1FFF
//Dia
//Dia
//Dia
//Dia
chi
chi
chi
chi
bat
ket
bat
ket
#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
//----------------------------------------------------------------------------
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();
}
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
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).
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;
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
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
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;
}
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*)ðBuffer[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*)ðBuffer[0]);
IPProcess( len-ETH_HEADER_LEN, (struct
ntIPHeader*)ðBuffer[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
//
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".
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
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.
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"
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;
};
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:
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(ðaddr, 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)
{
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
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.
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];
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
}
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
}
{
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.
};
#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
n y c 3 trng hp xy ra:
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
Truyn d liu:
Gii ta kt ni:
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 (;;)
{
//
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);
}
//--------------------------------------------------------------------------------------
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
SIGNAL
#endif //TIMER_H
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'
#include "uart.h"
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;
uartInit(UART_BAUDRATE);
}
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;}
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:
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;
tcp.h :
Code:
//---------------------------------------------------------------------------// Writen by NTTam - PTITHCM
//---------------------------------------------------------------------------#ifndef TCP_H
#define TCP_H
#endif //TCP_H
{
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
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);
}
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);
}
//-------------------------------------------------------------------------------------//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);
}
}
}
}
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):
>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
thch cho code thy nn qu. Vit gii thch cho code c khi cn kh hn vit code
udp.h
Code:
//---------------------------------------------------------------------------// Writen by NTTam - PTITHCM
//---------------------------------------------------------------------------#ifndef
UDP_H
#define UDP_H
//---------------------------------------------------------------------------#endif
//UDP_H
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.
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;
Code:
tcpHeader->seqNumber = HTONL(pSession->seqNumber);
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);
Ghi gi tr cc c
Code:
tcpHeader->Flags = Flags;
Gi tr trng Window
Code:
tcpHeader->Window = HTONS(pSession->srcWin);//((NETSTACK_BUFFERSIZE-20-14));
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);
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
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
+ 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
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 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 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.
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
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
1
3
4
5
12
50
53
54
55
58
61
#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
10
3
}
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
//-------------------------------------------------------------------------------------//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 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*)ðGetBuffer()
[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;
}
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;
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();////
}
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;
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
</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>
</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"> </td>
</tr>
<tr>
<td>Sensor 01</td>
<td width="42">%AD0</td>
<td width="33"><sup>o</sup>C</td>
<td width="150"> </td>
</tr>
<tr>
<td>Sensor 02</td>
<td width="42">%AD1</td>
<td width="33"><sup>o</sup>C</td>
<td width="150"> </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
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>
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\"> </td>"
"</tr>"
"<tr>"
"<td>Sensor 01</td>"
"<td width=\"42\">%AD0</td>"
"<td width=\"33\"><sup>o</sup>C</td>"
"<td width=\"150\"> </td>"
"</tr>"
"<tr>"
"<td>Sensor 02</td>"
"<td width=\"42\">%AD1</td>"
"<td width=\"33\"><sup>o</sup>C</td>"
"<td width=\"150\"> </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
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"
method;
*requestURI;
*version;
*header;
*body;
//end
//end
//end
//end
//
with
with
with
with
space
space
\n\r
\n\r\n\r
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
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[]={
AVR_Small_Webserver\r\n"
"WWW-Authenticate:
Basic realm=\"NeedPassword\""
"\r\nContent-Type:
text/html\r\n\r\n"};
AVR_Small_Webserver\r\n"
"WWW-Authenticate:
Basic realm=\"My AVR web server\""
"\r\nContent-Type:
text/html\r\n\r\n"};
httpSessionTable[MAX_HTTP_SESSION];
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:
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);
}
}
}
}
Code:
#include "tcp.h"
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
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 cng qui nh cc input m ngi dng nhp vo (gi tr check) s c gi
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
2.
20-07-12 13:47#420
nttam79
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;
//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.