You are on page 1of 149

1.

Hardware 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. 2. C s giao thc v thit k lu d liu C th ha v lu d liu vo ra ca giao thc (p dng cho phn lp trnh)

Nh vy phn lp trnh s chia ra cc module sau: - Module iu khin ENC28J60: nm trong file enc28j60.c v file header enc28j60.h, thm file enc28j60conf.h lu cc config. - Module giao thc Ethernet: gm cc file: ethernet.c v ethernet.h, thm file "packet.h" khai bo cc cu trc gi tin s dng trong b giao thc TCP/IP. - Module giao thc phn gii a ch Address Resolution Protocol, gm file arp.c v arp.h - Module giao thc IP gm ip.c v ip.h

- Module giao thc cp pht a ch IP ng DHCP (Dynamic Host Configuration Protocol) gm cc file dhcp.c v dhcp.h - Module giao thc UDP gm cc file udp.c v udp.h - Module giao thc TCP gm cc file tcp.c v tcp.h - Module giao thc HTTP gm cc file http.c v http.h - V mt s cc hm h tr khc (uart, timer,)

Sau khi to project, ta s c source file u tin l ntAVRnet.c. M file ny, thm vo hm main, chng trnh chnh, ni dung hm ny s c vit cui cng Code:
//--------------------------------------------------------------------------// Writen by NTTam - PTITHCM //--------------------------------------------------------------------------#include <avr/io.h> //--------------------------------------------------------------------------int { } main() return(0);

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


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

File ny s dng cha cc define v thng tin config chung cho ton project

Bi 3:-Lp trnh iu khin ENC28J60: Phn ny c tham kho cc project open source ca nc ngoi, thng tin v ti liu tham kho s c nu c th cui tut To cc file enc28j60.c, enc28j60.h v enc28j60conf.h. Add vo project ENC28J60 c iu khin bi mt tp kh ln cc thanh ghi iu khin, d liu (frame ehternet

gi/nhn) c lu tr trn 1 buffer. Vic c/ghi vo cc thanh ghi iu khin cng nh buffer d liu c thc hin qua giao tip SPI ti 1 a ch xc nh. M file enc28j60.h, khai bo a ch cc thanh ghi vo file Code:
//--------------------------------------------------------------------------// Writen by NTTam - PTITHCM //--------------------------------------------------------------------------#ifndef ENC28J60_H #define ENC28J60_H // ENC28J60 Control Registers // Control register definitions are a combination of address, // bank number, and Ethernet/MAC/PHY indicator bits. // - Register address (bits 0-4) // - Bank number (bits 5-6) // - MAC/PHY indicator (bit 7) #define ADDR_MASK 0x1F #define BANK_MASK 0x60 #define SPRD_MASK 0x80 // All-bank registers #define EIE 0x1B #define EIR 0x1C #define ESTAT 0x1D #define ECON2 0x1E #define ECON1 0x1F // Bank 0 registers #define ERDPTL (0x00|0x00) #define ERDPTH (0x01|0x00) #define EWRPTL (0x02|0x00) #define EWRPTH (0x03|0x00) #define ETXSTL (0x04|0x00) #define ETXSTH (0x05|0x00) #define ETXNDL (0x06|0x00) #define ETXNDH (0x07|0x00) #define ERXSTL (0x08|0x00) #define ERXSTH (0x09|0x00) #define ERXNDL (0x0A|0x00) #define ERXNDH (0x0B|0x00) #define ERXRDPTL (0x0C|0x00) #define ERXRDPTH (0x0D|0x00) #define ERXWRPTL (0x0E|0x00) #define ERXWRPTH (0x0F|0x00) #define EDMASTL (0x10|0x00) #define EDMASTH (0x11|0x00) #define EDMANDL (0x12|0x00) #define EDMANDH (0x13|0x00) #define EDMADSTL (0x14|0x00) #define EDMADSTH (0x15|0x00) #define EDMACSL (0x16|0x00) #define EDMACSH (0x17|0x00) // Bank 1 registers

#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 #define #define #define #define // Bank #define #define #define #define #define #define #define #define #define #define #define #define

EHT0 EHT1 EHT2 EHT3 EHT4 EHT5 EHT6 EHT7 EPMM0 EPMM1 EPMM2 EPMM3 EPMM4 EPMM5 EPMM6 EPMM7 EPMCSL EPMCSH EPMOL EPMOH EWOLIE EWOLIR ERXFCON EPKTCNT 2 registers MACON1 MACON2 MACON3 MACON4 MABBIPG MAIPGL MAIPGH MACLCON1 MACLCON2 MAMXFLL MAMXFLH MAPHSUP MICON MICMD MIREGADR MIWRL MIWRH MIRDL MIRDH 3 registers MAADR1 MAADR0 MAADR3 MAADR2 MAADR5 MAADR4 EBSTSD EBSTCON EBSTCSL EBSTCSH MISTAT EREVID

(0x00|0x20) (0x01|0x20) (0x02|0x20) (0x03|0x20) (0x04|0x20) (0x05|0x20) (0x06|0x20) (0x07|0x20) (0x08|0x20) (0x09|0x20) (0x0A|0x20) (0x0B|0x20) (0x0C|0x20) (0x0D|0x20) (0x0E|0x20) (0x0F|0x20) (0x10|0x20) (0x11|0x20) (0x14|0x20) (0x15|0x20) (0x16|0x20) (0x17|0x20) (0x18|0x20) (0x19|0x20) (0x00|0x40|0x80) (0x01|0x40|0x80) (0x02|0x40|0x80) (0x03|0x40|0x80) (0x04|0x40|0x80) (0x06|0x40|0x80) (0x07|0x40|0x80) (0x08|0x40|0x80) (0x09|0x40|0x80) (0x0A|0x40|0x80) (0x0B|0x40|0x80) (0x0D|0x40|0x80) (0x11|0x40|0x80) (0x12|0x40|0x80) (0x14|0x40|0x80) (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)

#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

(0x15|0x60) (0x17|0x60) (0x18|0x60) (0x19|0x60) 0x00 0x01 0x02 0x03 0x10 0x11 0x12 0x13 0x14

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

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

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

// SPI operation codes #define ENC28J60_READ_CTRL_REG 0x00 #define ENC28J60_READ_BUF_MEM 0x3A #define ENC28J60_WRITE_CTRL_REG #define ENC28J60_WRITE_BUF_MEM 0x7A #define ENC28J60_BIT_FIELD_SET 0x80 #define ENC28J60_BIT_FIELD_CLR 0xA0 #define ENC28J60_SOFT_RESET

0x40

0xFF

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


#define #define #define #define TXSTART_INIT TXSTOP_INIT RXSTART_INIT RXSTOP_INIT 0x0000 //Dia 0x05FF //Dia chi ket 0x0600 //Dia 0x1FFF //Dia chi bat dau buffer gui thuc buffer gui chi bat dau buffer nhan chi ket thuc buffer nhan

//Khai bao kich thuoc frame ethernet max va min #define MAX_FRAMELEN 1518 #define ETHERNET_MIN_PACKET_LENGTH 0x3C

Tip theo, m file enc28j60conf.h, thm vo cc khai bo v IO port s dng iu khin ENC28J60 v mt s thng tin cu hnh khc (a ch MAC) Code:
//--------------------------------------------------------------------------// Writen by NTTam - PTITHCM //--------------------------------------------------------------------------#ifndef ENC28J60CONF_H #define ENC28J60CONF_H // //Khai bao cac chan IO cho ENC28J60 #define ENC28J60_CONTROL_DDR DDRB #define ENC28J60_CONTROL_PORT PORTB #define ENC28J60_SPI_DDR DDRB #define ENC28J60_SPI_PORT PORTB // #define ENC28J60_CONTROL_CS 3 #define ENC28J60_CONTROL_RESET 4 #define ENC28J60_SPI_SCK 7 #define ENC28J60_SPI_MISO 6 #define ENC28J60_SPI_MOSI 5 #define ENC28J60_SPI_SS 4 #define ENC28J60_SPI_CS 3 // //Dinh nghia macro chon chip ENC28J60 #define ENC28J60_CS_LO() ENC28J60_CONTROL_PORT &= ~(1<<ENC28J60_CONTROL_CS); #define ENC28J60_CS_HI() ENC28J60_CONTROL_PORT |= (1<<ENC28J60_CONTROL_CS); // #define ETH_INTERRUPT INT2_vect

// #if defined (__AVR_ATmega32__) #define ETH_INT_ENABLE GICR |= (1<<INT2) #define ETH_INT_DISABLE GICR &= ~(1<<INT2) #endif #if defined (__AVR_ATmega644__) || defined (__AVR_ATmega644P__) #define ETH_INT_ENABLE EIMSK |= (1<<INT2) #define ETH_INT_DISABLE EIMSK &= ~(1<<INT2) #endif // MAC address for this interface #ifdef ETHADDR0 #define ENC28J60_MAC0 ETHADDR0 #define ENC28J60_MAC1 ETHADDR1 #define ENC28J60_MAC2 ETHADDR2 #define ENC28J60_MAC3 ETHADDR3 #define ENC28J60_MAC4 ETHADDR4 #define ENC28J60_MAC5 ETHADDR5 #else #define ENC28J60_MAC0 '0' #define ENC28J60_MAC1 'F' #define ENC28J60_MAC2 'F' #define ENC28J60_MAC3 'I' #define ENC28J60_MAC4 'C' #define ENC28J60_MAC5 'E' #endif #endif // ENC28J60CONF_H //---------------------------------------------------------------------------

Trc ht ta cn 1 hm c v 1 hm ghi d liu vo 1 a ch xc nh trn ENC28J60 qua SPI: M file enc28j60.c, thm vo cc hm (sau nh thm khai bo hm vo file header enc28j60.h na nh) Code:
//--------------------------------------------------------------------------// Writen by NTTam - PTITHCM //--------------------------------------------------------------------------#include <avr/io.h> #include "ntAVRnet.h" #include "enc28j60.h" #include "enc28j60conf.h" #include <avr/pgmspace.h> //--------------------------------------------------------------------------unsigned char enc28j60SPIRead(unsigned char op, unsigned char address) { unsigned char res; ENC28J60_CS_LO(); SPDR = op | (address & ADDR_MASK); while(!(SPSR & (1<<SPIF))); SPDR = 0x00;

while(!(SPSR & (1<<SPIF))); if(address & 0x80){ SPDR = 0x00; while(!((SPSR) & (1<<SPIF))); } res = SPDR; ENC28J60_CS_HI(); return res; } void enc28j60SPIWrite(unsigned char op, unsigned char address, unsigned char data) { ENC28J60_CS_LO(); SPDR = op | (address & ADDR_MASK); while(!(SPSR & (1<<SPIF))); SPDR = data; while(!(SPSR & (1<<SPIF))); ENC28J60_CS_HI(); }

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

V vit hm: Code:


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

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

} ENC28J60_CS_HI(); } void enc28j60WriteBuffer(unsigned int len, unsigned char* data) { ENC28J60_CS_LO(); SPDR = ENC28J60_WRITE_BUF_MEM; while(!(SPSR & (1<<SPIF))); while(len--) { SPDR = *data++; while(!(SPSR & (1<<SPIF))); } ENC28J60_CS_HI(); }

Da vo c s cc hm ny, ta xy dng cc hm c ghi thanh ghi iu khin, thanh ghi PHY ca ENC28J60: Code:
unsigned char enc28j60Read(unsigned char address) { enc28j60SetBank(address); return enc28j60SPIRead(ENC28J60_READ_CTRL_REG, address); } void enc28j60Write(unsigned char address, unsigned char data) { enc28j60SetBank(address); enc28j60SPIWrite(ENC28J60_WRITE_CTRL_REG, address, data); } unsigned int enc28j60PhyRead(unsigned char address) { unsigned int data; enc28j60Write(MIREGADR, address); enc28j60Write(MICMD, MICMD_MIIRD); while(enc28j60Read(MISTAT) & MISTAT_BUSY); enc28j60Write(MICMD, 0x00); data = enc28j60Read(MIRDL); data |= enc28j60Read(MIRDH); return data; } void enc28j60PhyWrite(unsigned char address, unsigned int data) { enc28j60Write(MIREGADR, address); enc28j60Write(MIWRL, data); enc28j60Write(MIWRH, data>>8); while(enc28j60Read(MISTAT) & MISTAT_BUSY); }

Cc hm trn cho php truy xut y vo tp thanh ghi ca ENC28J60 Tip theo ta vit tip 2 hm gi v nhn 1 gi tin: Code:

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

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

ERXNDH, HI8(RXSTOP_INIT MACON2, MACON1, MACON3, MAMXFLL, MAMXFLH, MABBIPG, MAIPGL, MAIPGH, MAADR5, MAADR4, MAADR3, MAADR2, MAADR1, MAADR0, };

), //end hi

0x00, (MACON1_MARXEN | MACON1_RXPAUS | MACON1_TXPAUS), ( MACON3_PADCFG0 | MACON3_TXCRCEN | MACON3_FRMLNEN), LO8(1518), HI8(1518), 0x12, //half duplex 0x12, 0x0C, //half duplex ENC28J60_MAC0, ENC28J60_MAC1, ENC28J60_MAC2, ENC28J60_MAC3, ENC28J60_MAC4, ENC28J60_MAC5

Trong hm ny, ta s cn hm delay_us delay Code:


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

Trong hm delay trn ta cn 1 thng tin l s chu k my ca CPU/micro giy, do ta cn thm cc thng tin ny vo file cu hnh chung: M file ntAVRnet.h, thm vo cc define sau: Code:
//--------------------------------------------------------------------------// Writen by NTTam - PTITHCM //--------------------------------------------------------------------------#ifndef NTAVRNET_H #define NTAVRNET_H #ifndef F_CPU #define F_CPU 12000000 // Cho toc do la 12MHz #endif //F_CPU #define CYCLES_PER_US ((F_CPU+500000)/1000000) //So chu ky lenh trong 1 micro giay

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

V y l hm khi ng ENC28J60: Code:


void enc28j60Init(void) { unsigned char i; unsigned int timeout=0; Enc28j60Bank = 0xFF; ENC28J60_CONTROL_DDR |= (1<<ENC28J60_CONTROL_CS); ENC28J60_CS_HI(); ENC28J60_SPI_PORT |= (1<<ENC28J60_SPI_SCK); //sck = hi ENC28J60_SPI_DDR |= (1<<ENC28J60_SPI_SS)|(1<<ENC28J60_SPI_MOSI)|(1<<ENC28J60_SPI_SCK); //SS,MOSI,SCK = OUT ENC28J60_SPI_DDR &= ~(1<<ENC28J60_SPI_MISO); //MISO = IN SPCR = (0<<SPIE)|(1<<SPE)|(0<<DORD)|(1<<MSTR)|(0<<CPOL)|(0<<CPHA)|(0<<SPR1)|(0<<SPR0 ); SPSR = (1<<SPI2X); delay_us(65000);delay_us(65000);delay_us(65000); enc28j60SPIWrite(ENC28J60_SOFT_RESET,0, ENC28J60_SOFT_RESET); delay_us(65000);delay_us(65000);delay_us(65000); while((!(enc28j60Read(ESTAT) & 0x01)) && (timeout<65000)){timeout++;}; if(timeout>=65000){timeout=0;} NextPacketPtr = RXSTART_INIT; for(i=0; i<2*22; i+=2){ enc28j60Write(pgm_read_byte(&enc28j60_config[i+0]),pgm_read_byte(&enc2 8j60_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.

Thnh vin chnh thc Tham gia Jan 2010 Bi vit

60 HI Anh nttam79, Anh hc PTITHCM ? Em l SV khoa in t PTITHCM. May gh, em ang lm ti AVR-Webserver. Cng cm ci ang v mch in, c code lm anh ? Hi vng anh tip tc hng dn lm v project ny. Anh cho em xin mail hoc ST nha. Tks Anh! Anh mn cho code vo khung th anh wrap[quote] html[quote] php[quote]=> ([QUOTE]copy code here[QUOTE]) l okey anh. V kt qu l nh th ny: unsigned char enc28j60SPIRead(unsigned char op, unsigned char address) { unsigned char res; ENC28J60_CS_LO(); SPDR = op | (address & ADDR_MASK); while(!(SPSR & (1<<SPIF))); SPDR = 0x00; while(!(SPSR & (1<<SPIF))); if(address & 0x80){ SPDR = 0x00; while(!((SPSR) & (1<<SPIF))); } res = SPDR; ENC28J60_CS_HI(); return res; }

Bi 4: Lp trnh giao thc ethernet HOT NG CA TCP/IP - D liu truyn t ng dng, n mt trong 2 giao thc vn chuyn (TCP hay UDP). Mt gi tin hay n v d liu (PDU) ca TCP/UDP thng c gi l segment (on d liu). - on d liu xung lp Internet, giao thc IP cung cp thng tin nh a ch lun l (a ch IP) v ng gi d liu vo 1 datagram, thng c gi l gi tin IP (IP packet). - Datagram IP n lp truy cp mng ( y l giao thc ethernet), v c ng gi vo 1 hay nhiu khung d liu (frame ethernet), sau a xung tng vt l (v d IC ENC28J60) gi i. Khung d liu c chuyn thnh mt lung cc bit truyn i trn mi trng mng. pha thu, qu trnh xy ra ngc li, tng vt l s nhn lung bit, khi phc li frame d liu, giao thc ethernet pha nhn s x l frame d liu ny, tch ra gi tin IP (IP packet) v y ln giao thc IP nu y l gi IP. Cn trong trng hp bn trong frame ethernet khng phi l 1 gi IP m l 1 gi tin ca giao thc ARP th n s y gi ny sang cho giao thc ARP x l (xem li hnh minh ha lu d liu gia cc giao thc). Ti tng giao thc IP, gi IP s c x l, xc nh xem d liu cha bn trong l ca giao thc no (TCP, UDP, hay ICPM) v chuyn n giao thc tng ng x l tip theo. Cui cng, giao thc k (TCP, UDP, hay ICMP s x l tip segment d liu nhn c, xc nh xem d liu ny l ca ng dng no (v d nh HTTP hay DHCP,) v chuyn d liu n ng dng tng ng

Trc ht, ta cn nm r cu trc ca tt c cc gi tin ca mi giao thc c th x l c thng tin cha trong n. Ta to 1 file header mi l packet.h, file ny s dng cha m t cu trc ca tt c cc gi tin ca cc giao thc s dng trong project ny: Code:
//--------------------------------------------------------------------------// Writen by NTTam - PTITHCM //--------------------------------------------------------------------------#ifndef PACKET_H #define PACKET_H #endif //PACKET_H

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

K n l header ca frame ethernet: Code:


//------------------------------------------------------------------------------------//Ethernet header // Gom 14 byte: // 06 byte dia chi dich // 06 byte dia chi nguon // 02 byte type (cho biet frame ethernet mang ben trong loai du lieu gi) #define ETH_HEADER_LEN 14

struct ntEthHeader { struct ntEthAddr desAddr; struct ntEthAddr srcAddr; unsigned int type; };

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

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

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

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

//--------------------------------------------------------------------------#include <avr/io.h> #include <avr/pgmspace.h> #include "packet.h" #include "enc28j60.h" #include "enc28j60conf.h" #include "ethernet.h"

File ethernet.h Code:


//--------------------------------------------------------------------------// Writen by NTTam - PTITHCM //--------------------------------------------------------------------------#ifndef ETHERNET_H #define ETHERNET_H #endif //ETHERNET_H

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

#endif #ifndef #define #endif // #ifndef ETHERNET_BUFFER_SIZE

IP_HEADER_LEN #define IP_HEADER_LEN 20 //IP_HEADER_LEN TCP_HEADER_LEN TCP_HEADER_LEN 20 //TCP_HEADER_LEN

#define ETHERNET_BUFFER_SIZE (700+ETH_HEADER_LEN+IP_HEADER_LEN+TCP_HEADER_LEN) #endif

S d ta thm iu kin (#ifndef #endif) l v thc ra kch thc Header TCP v IP s c nh ngha trong file packet.h, MTU_SIZE s c nh ngha trong phn config thng tin chung ca chng trnh, do hin nay ta cha vit cc phn nn tm thi nh ngha trc. Sau khai bo buffer dnh cho frame ethernet trong file source (ethernet.c): Code:
unsigned char ethBuffer[ETHERNET_BUFFER_SIZE];

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


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

enc28j60Write(MAADR1, *macaddr++); enc28j60Write(MAADR0, *macaddr++); } //------------------------------------------------------------------------------------//Ham tra lai con tro den buffer ethernet (tren RAM cua CPU) unsigned char* ethGetBuffer(void) { return ethBuffer; }

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

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

Trong hm ny ta c s dng nh ngha vector ngt (ISR), do ta cn include file tng ng vo. Thm dng ny vo u file "ehternet.c" Code:
#include <avr/interrupt.h>

Trong hm ny, ta s dng 2 bin ton cc l eth_got_frame v time_watchdog, hai bin ny cn c khai bo trong file enc28j60.c (nn du file) Code:

unsigned char eth_got_frame = 0; volatile unsigned int time_watchdog;

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

{ #ifdef ETH_DEBUG printf("ARP packet\r\n"); #endif arpArpProcess(len, ethBuffer ); }else{ #ifdef ETH_DEBUG printf("Unknown packet:%x\r\n",ethPacket->type); #endif ethInit(); } ETH_INT_ENABLE; } return; } //-------------------------------------------------------------------------------------

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

Lu l trong hm ny ta c gi cc hm ca giao thc lp trn (IP v ARP). l cc hm arpIPPacketIn, IPProcess, v arpArpProcess. Cc hm ny ta vn cha vit nn khi bin dch file ethernet.c s c bo li thiu cc hm ny. cho mc ch debug sau ny, trong hm ta c s dng hm xut ra cng serial l printf. Hm ny cc bn t vit ly dng uart nh. Trong ni dung hng dn ny tp trung vo giao thc TCP/IP thi. Sau khi x l xong frame, ta cn enable ngt ngoi tr li. n y l c bn xong giao thc ethernet, tip theo s l giao thc IP v ARP, rc ri hn nhiu.

Bi 5: Lp trnh cho giao thc IP (Internet Protocol) v giao thc ARP (Address Rolution Protocol) Trc ht, ta cn tm hiu v hot ng ca giao thc IP.

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

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

Note: xem c bng arp cache trn my tnh ca mnh, cc bn c th m ca s command (vo Start->Run->g cmd, nhn Enter), sau g lnh "arp -a".

By gi ta bt tay vo vit code: Vic trc tin phi lm l khai bo cu trc header IP v cu trc gi ARP trong file packet.h. Cu trc ca gi IP nh sau:

- ngha cc field trong header IP: + Version (c chiu di 4 bit): cho bit phin bn ca giao thc, i vi trng hp ca chng ta, giao thc l IP version 4, trng ny s lun c gi tr l 4 (0100) + Header Length (4 bit): cho bit chiu di ca header IP, tnh theo n v 4 byte (32 bit) + TOS (8 bit): Type of Service + Total Length (16 bit): 16 bit tng chiu di ca gi IP gm c phn header + Identification (16 bit): dng nhn din cc phn on ca gi IP + Flags: gm 3 bit . Bit u tin: khng s dng . Bit 2: DF (Dont Fragment) = 1 c ngha l khng phn on gi ny . Bit 3: MF (More Fragment) = 0 => y l phn on cui cng + Fragmented offset (13 bit): di (n v 8 byte) tnh t im bt u ca Header ti im bt u ca phn on (3 trng trn: Identification, Flags, Fragmented offset dng cho trng hp c bit khi ta cn chia on d liu ban u thnh nhiu phn on, ng gi trong cc gi tin nh hn, khi ta cn dng cc trng ny cho mc ch rp li cc phn on khi phc li on d liu ban u, trong project ca chng ta s khng c x l trng hp ny). + TTL (Time to Live) (8 bit): thi gian tn ti trn mng hoc s chng trn mng m gi i qua trc khi b hy b + Protocol (8 bit): nhn din Protocol trn lp IP + Header checksum (16 bit): sa sai cho phn Header

+ Cc vng a ch ngun, a ch ch: a ch IP 32 bit + Option: cc ty chn dng cho vic kim tra: Loose source routing, Strict source routing, Record route v Timestamp + Padding: Gm cc s zero c thm vo sao cho chiu di ca vng Header l bi s ca 32 bit (Trong phm vi project ca chng ta, s khng c phn option v padding) Vy ta khai bo trong file packet.h ni dung nh sau: Code:
//------------------------------------------------------------------------------------//Cau truc IP header struct ntIPHeader { unsigned char verHdrLen; unsigned char ToS; unsigned int Len; unsigned int IDNumber; unsigned int Offset; unsigned char TTL; unsigned char Protocol; unsigned int Checksum; unsigned long srcIPAddr; unsigned long desIPAddr; unsigned char Option[4]; }; #define IP_HEADER_LEN 20 #define IP_PROTO_ICMP #define IP_PROTO_TCP #define IP_PROTO_UDP 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 hwType; unsigned int protocol; unsigned char hwLen; unsigned char protoLen; unsigned int opcode; struct ntEthAddr shwaddr; unsigned long sipaddr; struct ntEthAddr dhwaddr; unsigned long dipaddr; }; #define ARP_OPCODE_REQUEST 1 #define ARP_OPCODE_REPLY 2 #define ARP_HWTYPE_ETH 1

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

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.

Thy cho em hi ch ny, v va c em va tng tng thc th cho d hiu. Trong mi frame ethernet u cha 2 a ch MAC: mt a ch ca host gi v 1 a ch ca host nhn . Cu hi:S host truyn nhn trong trng hp ny l bao nhiu : 2 hay >2 host ? V em ngh 2 host l TH ring, 1 host truyn 1 host nhn, th host nhn check IP l chnh n. Nu host nhn c frame m n kim tra ko phi IP add(dst) ca n th n s x l nh th no, c phi lc ny IP add(dst) l IP broadcast? V sau ti mt host no , check IP add l ca chnh n th TH1 c xy ra, phi ko ? Em lin tng TCP/IP lc ny x l IP nh mt Router check IP cho c 1 mng LAN, ...kt ni vi n. Nu frame c gi cho tt c my tnh trong LAN, th s ko c host ch c th no ? Nu vi HTTP, hay 1 ng dng no khc th iu ny c th c, nhng vi cc ng Email chng hn, cn tnh bo mt ring t th IPbroadcast li ko c- do cc my u nhn c frame x l. EM c vi cu, ko bit ng sai th no? Cu hi ca em thc ra rt hay, vn ny ti khng gii thch chi tit trong phn giao thc ethernet. - Giao thc ethernet ch h tr 2 hnh thc truyn: unicast: tc l 1 host gi, 1 host nhn; v broadcast, tc l 1 host gi, tt c cc host trong mng LAN u nhn. - Trong mng LAN c bn, s dng 1 HUB kt ni cc my tnh vi nhau trong mng LAN. Khi mt my tnh gi i mt frame ethernet, bt k l n gi unicast hay broadcast, th tt c cc my tnh trong mng LAN (kt ni vi HUB) u nhn c frame . Nhng mi my tnh s i chiu a ch MAC nhn vi a ch ca chnh n ( y ch kim tra a ch MAC, khng kim tra a ch IP, khi ln giao thc IP th mi kim tra a ch IP), v cc host s ch nhn frame v chuyn ln giao thc IP trong 2 trng hp: + Hoc a ch l ca chnh n + Hoc a ch l broadcast

- Vy iu g s xy ra nu mt my tnh no ph v lut chi, nhn d liu khng phi dnh cho n, nh vy phi chng n c th nghe trm d liu gi cho my tnh khc. - Cu tr li y l: ng nh vy, mng LAN kiu ny hon ton khng c bo mt, vi cc phn mm nghe trm d liu, mt my tnh c th nghe trm d liu ca cc my khc trong cng mng LAN. - y thit b HUB dng kt ni cc my tnh to thnh mng LAN ch n gin l khi nhn c d liu n 1 port ca n, n s khuych i v pht ra li tt c cc port, tt c my tnh ni n n u nhn c d liu. [Flash]http://www.shareswf.com/media/games/swf/16193.swf[/Flash] [flash=300,200]http://www.shareswf.com/media/games/swf/16193.swf[/flash] [FLASH=300,300]http://www.shareswf.com/media/games/swf/16193.swf[/FLASH] - Tt nhin ngi ta cng nhn ra hn ch ca HUB, cng nh mt s hn ch khc, v pht trin mt thit b "thng minh" hn HUB, l SWITCH. - V hnh thc, SWITCH cng c nhiu port v dng kt ni cc my tnh to thnh mng LAN ging HUB, tuy nhin s khc bit l: mi khi nhn c d liu n 1 port ca n, SWITCH s kim tra a ch MAC ch trn frame, sau n tm xem my tnh c a ch MAC tng ng ang nm port no ca n, v chuyn d liu n port . Nh vy ch c my tnh nhn c d liu m thi. [FLASH]http://www.swfcabin.com/open/1320370008[/FLASH] Hin nay hu ht cc mng LAN l dng SWITCH, tr cc thit b c s port t (<=5 port) l cn dng HUB. Vic gi broadcast trn mng LAN ch dng cho mt s trng hp c bit, v d nh cho giao thc ARP, hay khi giao thc IP yu cu gi broadcast (giao thc IP th c 3 hnh thc gi l unicast, multicast v broadcast). a ch MAC broadcast c qui nh l FF:FF:FF:FF:FF:FF. Mc nh, vic gi broadcast ra ngoi phm vi mng LAN l khng c php, cc router s chn cc bn tin broadcast v khng cho n ra khi phm vi mng LAN. Hy vng cu tr li trn gii p c thc mc ca em, nu cn cha r c hi tip nh.

Cu hi:ARP: Em ngh ti 1 ci l: mnh ko nh 192.xxx.x.x na m c th nh ch no nh avrnet v Enter th c hin th c webserver khng ? V vai tr ca ARP trong trng hp ny th no. Li mt cu hi rt ng bn lun na, tuy nhin vn ny khng thuc giao thc ARP m thuc mt h thng khc, ta gi l h thng tn min (domain name system). ng ra, my tnh ch gi v nhn d liu trn mng da vo a ch IP. Tc l l ra truy cp vo trang ch yahoo chng hn, ta phi g a ch IP server ca yahoo: http://98.137.149.56 (cc bn c th th). Tuy nhin r rng l cch ny qu kh nh vi ngi s dng, do ngi ta mi ngh ra mt loi a ch gi nh d nh hn, l tn min (domain name) nh vy thay v g: http://98.137.149.56 ta c th g: http://www.yahoo.com.

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

Thy c th so snh Add lun l v Add MAC c khng ? Ti sao trng MAC ch khi truyn ra internet li l a ch Gateway? gateway ging MAC im no, m li c in vo MAC ch? V ARP cache c ging vi bng NAT ip khng ? Em thy na l. C phi Gateway and local IP(mng LAN) ca host s cho a ch MAC ca host ch khng ? Mong thy tr li! hiu v 2 loi a ch ta c th hnh dung nh th ny: Gi s ta cn gi 1 bc th loanh quanh trong xm, ta ch cn ghi tn ngi nhn l c, trong xm s d dng xc nh ng Nguyn Vn A ch no. Tuy nhin khi gi th i trong phm vi c nc, nu ta ch ghi tn ngi nhn, thm ch c thm c ngy thng nm sinh v s chng minh th bo m khng s b trng, th bu in cng b tay v khng bit ng Nguyn Vn A u, v vi a ch ny (gm tn, ngy thng nm sinh, s chng minh th) th d khng s trng a ch, th n cng khng th gip ta xc nh c ng Nguyn Vn A ang tnh, thnh ph, ng no. Vy ta cn mt cch ghi a ch khc, m nhn vo ta xc nh c ni cn chuyn th ti, v d tnh... huyn.... ng.... s nh.

iu ny hon ton tng t vi a ch IP v a ch MAC: a ch MAC mc d l bo m khng trng nhau, nhng nhn vo n ta khng th bit host c a ch MAC ang u? M, Vit Nam hay Trung Quc,...? Do a ch MAC ch s dng c trong mng LAN, ni s lng my tnh l t, cc thit b nh SWITCH c th bit ht cc a ch MAC trong mng. gi d liu ra ngoi mng LAN, ta cn 1 loi a ch khc, mt a ch m khi nhn vo ta bit ngay l host tng ng ang M hay Vit Nam, thm ch nu Vit Nam th thuc mng ca nh cung cp dch v no. a ch tha mn yu cu ny chnh l a ch IP. S d nh vy v trong a ch IP, ngi ta chia thnh 2 phn, phn u l a ch mng, cho bit my tnh ang thuc mng no, phn sau l a ch host, gip phn bit cc my tnh trong mng. Ta c th d dng nhn thy iu ny: cc my tnh trong cng mng th phn u ca a ch IP l ging nhau. Nhn vo 1 a ch IP, ta s bit ngay my tnh tng ng ang nc no. Trong phm vi mng LAN, vic chuyn d liu n ch v mt vt l hon ton ch cn da vo HUB hay SWITCH, tuy nhin khi gi ra ngoi mng LAN th HUB hay SWITCH s b tay, v s khng bit c a ch MAC ca my tnh bn ngoi. Lc ny, HUB hay SWITCH s chuyn gi tin n mt thit b khc c kh nng a gi tin ra khi mng LAN, chnh l Gateway, thit b kt ni gia mng LAN vi bn ngoi. V r rng SWITCH chuyn gi tin n Gateway, th by gi a ch MAC ch trong frame ethernet phi l a ch MAC ca Gateway. ARP cache hon ton khc bng NAT IP (NAT-Network Address Translation) Trong project ny s hng dn n kt ni, ci t modem, ng k tn min, thit k website,... ni chung t A-Z lun.

C l mnh cn dng li gii thch r hn v hot ng ca 2 giao thc IP v ARP mt cht, cng nh cc s dng 2 loi a ch IP v MAC trn mng, trc khi vit code tip, tuy hi di dng 1 cht nhng s gip mi ngi hiu r hn cch thc lm vic ca TCP/IP, nh vy th s d hiu code hn v c th t vit hay sa i code c d dng. Ta hy xem xt 1 mng v d nh sau: - Mng LAN ti nh gm 3 my tnh v 1 board mch ca chng ta kt ni vo ADSL router, t ni vo mng ca nh cung cp dch v. - Cc bn cng cn bit l thc ra modem ADSL hay ADSL router m ta dng nh, tht ra bn trong n gm 3 thit b: mt HUB m rng s lng port, cho php nhiu my tnh c th cng kt ni vo mng; mt Router IP ng vai tr Gateway, thc hin chc nng nh tuyn gia mng bn trong (LAN) v mng bn ngoi (WAN); v cui cng l 1 modem (Modulation - Demodulation) c th truyn d liu trn ng dy ADSL.

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

Bc 3: ARP s cp nht bng ARP cache v tr li li cho giao thc IP. Bc 4: giao thc IP dng thng tin ny in vo frame ethernet v chuyn sang giao th ethernet gi i.

B-Trng hp gi ra ngoi mng LAN Nu vn lm theo cch c th s xy ra trng hp nh sau:

Nh vy, nu vn lm theo cch c, vic gi d liu s tht bi. Mi vic phi c tin hnh nh sau:

Vy by gi ta bt u vit code cho cc giao thc ip v arp: Ta to file ip.c vi ni dung ban u Code:
//--------------------------------------------------------------------------// Writen by NTTam - PTITHCM //--------------------------------------------------------------------------#include <avr/io.h> #include "packet.h" #include "ethernet.h" #include "arp.h" #include "ip.h"

V file header ip.h Code:


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

Ta cng to 2 file tng ng cho giao thc ARP: arp.c Code:


//--------------------------------------------------------------------------// Writen by NTTam - PTITHCM //--------------------------------------------------------------------------#include <avr/io.h> #include "packet.h" #include "ethernet.h" #include "arp.h" #include "ip.h"

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

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

M tip file ip.c, khai bo bin IpMyConfig c kiu l struct ipConfig Code:
//------------------------------------------------------------------------------------struct ipConfig IpMyConfig; ///< Local IP address/config structure

Tip theo ta vit trong file ip.c mt s hm chc nng cho giao thc ny: u tin l hm tnh trng kim tra li (checksum) trong Header IP. Nu cc bn xem li

phn cu trc Header ca IP s thy n c 1 trng kim tra li cho Header (khng bao gm data). Trng ny gip pha nhn gi IP kim tra li xem thng tin cha trong Header (rt quan trng) c b sai trong qu trnh truyn hay khng. Nu c sai st, gi tin s b hy b m khng x l. Pha pht trc khi gi phi tnh gi tr checksum v ghi n vo trng checksum trong header. Pha thu khi nhn gi tin s t mnh tnh li check sum 1 cch c lp, sau so snh vi checksum m pha pht tnh (lu trong header) nu c khc bit th tc l c li xy ra, v gi tin s b hy. Vy hm ny s c giao thc IP s dng c khi gi v nhn gi tin. Code:
//------------------------------------------------------------------------------------//Ham tinh checksum cho goi ip unsigned int ipChecksum(unsigned char *data, unsigned int len) { register unsigned long sum = 0; for (;;) { if (len < 2) break; sum += *((unsigned int *)data); data+=2; len -= 2; } if (len) sum += *(unsigned char *) data; while ((len = (unsigned int) (sum >> 16)) != 0) sum = (unsigned int) sum + len; return (unsigned int) sum ^ 0xFFFF; }

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

// set local addressing IpMyConfig.ip = myIp; IpMyConfig.netmask = netmask; IpMyConfig.gateway = gatewayIp; // set ARP association ethGetMacAddress(ethaddr.addr); arpSetAddress(&ethaddr, myIp); }

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

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

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

V hm in ra cc thng s cu hnh IP Code:


//------------------------------------------------------------------------------------//In ra cac gia tri cau hinh cho giao thuc IP void ipPrintConfig(struct ipConfig* config) { printf("IP Addr : "); ipPrintAddr(config->ip); printf("\n\r"); printf("Netmask : "); ipPrintAddr(config->netmask); printf("\n\r");

printf("Gateway : "); ipPrintAddr(config->gateway); }

printf("\n\r");

Lu : truy xut c cc hm trong module ethernet.c, chng ta phi thm phn khai bo (declare) cc hm ny vo file header tng ng ethernet.h nh. T nay vic ny l ng nhin, mnh s khng nhc li na. Ta c s dng hm printf xut d liu ra cng COM, cc bn t vit nh. Mt s hm thuc module giao thc ARP, ta vn cha vit, c gi y, nn s to thng bo li thiu hm khi bin dch. Trn y l mt s hm cng c cung cp cc chc nng h tr cho giao thc IP. Tip theo s l nhng hm x l chnh trong giao thc IP, bao gm hm gi v nhn gi tin IP. Ta vit tip hm thc hin gi 1 gi tin qua giao thc IP: Code:
//------------------------------------------------------------------------------------//Ham gui 1 goi IP void ipSend(unsigned long dstIp, unsigned char protocol, unsigned int len, unsigned char* ipData) { struct ntEthHeader* ethHeader; struct ntIPHeader* ipHeader; ipHeader = (struct ntIPHeader*)(ipData - IP_HEADER_LEN); ethHeader = (struct ntEthHeader*)(ipData - IP_HEADER_LEN ETH_HEADER_LEN); len += IP_HEADER_LEN; ipHeader->desIPAddr = HTONL(dstIp); ipHeader->srcIPAddr = HTONL(IpMyConfig.ip); ipHeader->Protocol = protocol; ipHeader->Len = HTONS(len); ipHeader->verHdrLen = 0x45; ipHeader->ToS = 0; ipHeader->IDNumber = 0; ipHeader->Offset = 0; ipHeader->TTL = IP_TIME_TO_LIVE; ipHeader->Checksum = 0; ipHeader->Checksum = ipChecksum((unsigned char*)ipHeader, IP_HEADER_LEN); if( (dstIp & IpMyConfig.netmask) == (IpMyConfig.ip & IpMyConfig.netmask) ) { arpIpOut((unsigned char*)ethHeader,0); } else { arpIpOut((unsigned char*)ethHeader,IpMyConfig.gateway); // gateway send } len += ETH_HEADER_LEN; #ifdef IP_DEBUG printf("Sending IP packet\r\nAddr: "); ipPrintAddr(dstIp);printf("\n\rMAC: ");

// loca

ethPrintAddr(&(ethHeader->desAddr)); #endif ethSendFrame(len, (unsigned char*)ethHeader); }

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

C thi gian s gii thch ngha ca trng TTL sau nh. V hm x l khi nhn c 1 gi tin IP: Code:
//------------------------------------------------------------------------------------//Ham xu ly goi IP, duoc goi boi giao thuc ethernet khi paket type duoc xac dinh la IP void IPProcess(unsigned int len, struct ntIPHeader* packet) { // check IP addressing, stop processing if not for me and not a broadcast if( (HTONL(packet->desIPAddr) != ipGetConfig()->ip) && (HTONL(packet->desIPAddr) != (ipGetConfig()->ip|ipGetConfig()>netmask)) && (HTONL(packet->desIPAddr) != 0xFFFFFFFF) ) return; // handle ICMP packet if( packet->Protocol == IP_PROTO_ICMP ) { #ifdef IP_DEBUG printf("IP->Rx: ICMP/IP packet\r\n"); //icmpPrintHeader((icmpip_hdr*)packet); #endif

icmpIpIn((struct ntIPHeader*)packet); } else if( packet->Protocol == IP_PROTO_UDP ) { #ifdef IP_DEBUG printf("IP->Rx: UDP/IP packet\r\n"); //debugPrintHexTable(NetBufferLen-14, &NetBuffer[14]); #endif UDPProcess(len, ((struct ntIPHeader*)packet) ); } else if( packet->Protocol == IP_PROTO_TCP ) { #ifdef IP_DEBUG printf("IP->Rx: TCP/IP packet\r\n"); #endif TCPProcess((unsigned char *)packet,len-((packet->verHdrLen & 0x0F)<<2)); } else { #ifdef IP_DEBUG printf("IP->Rx: IP packet\r\n"); #endif } } //-------------------------------------------------------------------------------------

Gii thch: - Khi nhn c 1 gi IP, vic u tin giao thc IP cn lm l kim tra li a ch IP xem c phi l gi cho mnh khng: v ta ch nhn nu ng a ch hoc a ch l IP broadcast (lu y l a ch IP broadcast (255.255.255.255) nh, khng phi MAC broadcast). - Mc d trc , giao thc ethernet kim tra a ch MAC ri, nhng giao thc IP vn kim tra li a ch IP. - Tip theo, ta kim tra trng protocol trong header IP xem giao thc lp trn (trn giao thc IP) no gi gi tin ny (TCP, UDP, hay ICMP) v gi hm ca giao thc tng ng x l. Vy l xong giao thc IP. Tip theo ta vit code cho giao thc ARP. Trc ht ta cn xc nh mt s gi tr hng dnh cho giao thc ARP. l s dng ti a trong bng ARP cache, thi gian timeout cho mi cp a ch trong bng ARP cache. Ta m file arp.h thm vo cc nh ngha ny: Code:
//------------------------------------------------------------------------------------#include "packet.h" //------------------------------------------------------------------------------------#ifndef ARP_TABLE_SIZE #define ARP_TABLE_SIZE 8 #endif #ifndef ARP_CACHE_TIME_TO_LIVE

#define ARP_CACHE_TIME_TO_LIVE 250 #endif

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

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

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

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


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

Hm tm kim 1 a ch IP trong bng ARP cache, tr li v tr ca entry tng ng vi a ch IP trong bng ARP cache: Code:
//------------------------------------------------------------------------------------unsigned char arpSearchIP(unsigned long ipaddr) { unsigned char i; for(i=0; i<ARP_TABLE_SIZE; i++) { if((ARPTable[i].ipAddr == ipaddr) && (ARPTable[i].time != 0)) { return i; } } return -1; }

Hm cp nht 1 entry trong bng ARP Code:


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

Hm x l khi nhn c 1 bn tin ARP (do lp giao thc ethernet chuyn n): Code:
//------------------------------------------------------------------------------------void arpArpProcess(unsigned int len, unsigned char* ethFrame)

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

hm x l khi nhn c 1 gi IP: nh ni trc y trong ni dung v ARP, c 2 cch cp nht ARP l thng qua ARP request v thng qua cc gi IP n. Mi khi c 1 gi IP n, l d nhin l gi ny s c giao thc IP x l, ARP khng can thip vo qu trnh x l . Tuy nhin trong mi gi IP n c 2 thng tin quan trng m ARP cn: l a ch IP v a ch MAC ca host gi gi tin . ARP s dng cp a ch ny cp nht ARP cache. Code:
//------------------------------------------------------------------------------------void arpIPPacketIn(unsigned char* ethFrame) { struct ntEthHeader* ethHeader;

struct ntIPHeader* ipHeader; ethHeader = (struct ntEthHeader*)ethFrame; ipHeader = (struct ntIPHeader*)(ethFrame + ETH_HEADER_LEN); arpUpdateEntry(ethHeader->srcAddr,HTONL(ipHeader->srcIPAddr)); } //-------------------------------------------------------------------------------------

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

Trong hm ArpIpOut trn, c 1 ch "lch lut", khng tun th ng nguyn tc lm vic ca ARP, cc bn tm ra, nu c ai tm ra mnh s gii thch ti sao li lm nh vy. Hm kim tra timeout ca cc entry trong ARP cache. hm ny s c gi nh k bi ngt timer kim tra xem c entry no "qu date" hay khng, v hy cc entry . Code:
//------------------------------------------------------------------------------------void arpTimer(void) //Goi moi 10s { int index;

for(index=0; index<ARP_TABLE_SIZE; index++) { if(ARPTable[index].time) ARPTable[index].time--; } } //-------------------------------------------------------------------------------------

Cc hm phc v cho mc ch debug: Code:


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

Sau khi vit hm xong, nh thm declare vo file header tng ng nh.

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

Bi 5: Cc giao thc lp vn chuyn Vy l xong cc giao thc lp 3, IP v giao thc h tr cho n l ARP. By gi chng ta s chuyn sang cc giao thc lp 4, lp vn chuyn (Transport Layer). l TCP (Transport Control Protocol) v UDP (User Datagram Protocol), ngoi ra cn c mt giao thc iu khin cng c th xp vo y, l ICMP (Internet Control Message Protocol). Trc ht ta ni qua v chc nng v hot ng c bn ca cc giao thc ny trc khi bt tay vo vit code. Nu ni phn lp trnh giao thc IP phc tp gp i so vi ethernet th c l lp trnh giao thc TCP phi phc tp gp i c IP v ARP cng li. V trong giao thc TCP, ta phi x l cc vn lin quan n qu trnh bt tay gia hai pha khi truyn d liu. Phi h tr cng lc nhiu kt ni TCP n cc host khc (v d webserver phi c kh nng x l khi c ng thi vi ba my tnh cng truy cp vo website), v lin quan cht ch n lp ng dng v dch v. Chnh v vy ta phi tm hiu k hot ng ca n. So vi TCP th UDP n gin hn nhiu. Cn ICMP l mt giao thc dng chuyn qua li cc bn tin iu khin trn mng. V d khi ta g lnh ping trn my tnh, s c 1 bn tin iu khin l ICMP request c gi n a ch ch. V ni nhn c ICMP request s tr li li bng bn tin ICMP reply. Nu vit xong giao thc ny th chng ta c th ping n board mch ca chng ta c ri. C l ta bt u vi giao thc ICMP. Giao thc thng ip iu khin Internet (Internet Control Message Protocol) c cc router v host trn mng Internet s dng thng bo v cc vn gp phi trong qu trnh nh tuyn d liu. Vic ny c thc hin bng cch gi qua li cc bn tin thng bo v cc s kin xy ra trn mng. Cc bn tin ny c gi l thng ip iu khin Internet (Internet Control Message). C rt nhiu bn tin nh vy, c dng trong nhng trng hp c th khc nhau. Di y l 1 s bn tin ICMP thng gp: - Bn tin Echo Request v Echo Reply: s dng cho qu trnh kim tra (lnh ping). - Bn tin Source Quench: yu cu host ngun gim tc truyn d liu. - Bn tin Destination Unreachable: thng bo cho host ngun bit datagram khng th chuyn c n ch. - Bn tin Time Exceeded: thng bo 1 gi tin b hy do TTL = 0. - Bn tin Fragmentation Needed: thng bo cho host ngun bit 1 datagram c c DF (Dont Fragment) = 1, nhng router cn phn on datagram ny chuyn n chng k tip. Trong phm vi project ny, chng ta ch lp trnh cho 2 bn tin l Echo Request v Echo

Reply phc v cho vic ping n board mch ca chng ta. y l cu trc ca bn tin ICMP:

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

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

V file icmp.h Code:


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

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

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

Chc nng hm ny kh n gin: ta kim tra trng Type xem y c ng l bn tin Echo Request hay khng. Nu ng ta gi hm icmpEchoReply (s vit k tip) tr li. Tip theo l hm icmpEchoReply gi bn tin Echo Reply tr li cho bn tin Echo Request Code:
//------------------------------------------------------------------------------------//Ham gui di ban tin tra loi cho Echo Request (Echo Reply) void icmpEchoReply(struct ntIPHeader* ipHeader) { unsigned long tempIp;

unsigned char* ethFrame; struct ntICMPHeader* icmpHeader; icmpHeader = (struct ntICMPHeader*)((unsigned char*)ipHeader + IP_HEADER_LEN); icmpHeader->Type = ICMP_TYPE_ECHOREPLY; icmpHeader->Checksum = 0; icmpHeader->Checksum = ipChecksum((unsigned char*)icmpHeader, HTONS(ipHeader->Len)-IP_HEADER_LEN); tempIp = ipHeader->desIPAddr; ipHeader->desIPAddr = ipHeader->srcIPAddr; ipHeader->srcIPAddr = tempIp; ethFrame = ((unsigned char*)ipHeader); ethFrame -= ETH_HEADER_LEN; arpIpOut(ethFrame, 0); #ifdef ICMP_DEBUG icmpPrintHeader(ipHeader); #endif ethSendFrame(HTONS(ipHeader->Len)+ETH_HEADER_LEN, ethFrame); }

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

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

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


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

Vy l xong giao thc ICMP. n y vn cha ping c nh, v ta vn cha vit ngt timer phc v cho cc hm kim tra thi gian timeout v ni dung cho chng trnh chnh (main()).

Giao thc TCP (Transport Control Protocol): Tip theo l giao thc kh chu nht trong chng giao thc TCP/IP. chnh l giao thc TCP (Transport Control Protocol) Nhim v chnh ca TCP l m bo d liu n ch ng v trn mt mi trng truyn ti khng ng tin cy (IP). hiu chc nng v cch m TCP thc hin chc nng , ta xem minh ha sau y:

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

Ch thch: - S port ch v s port ngun: phn bit cc tin trnh ng dng ang xy ra trong my tnh - Cc s sequence v Acknowledgement: s sequence phn bit cc segment khc nhau trong mt dng d liu, cc s Acknowledgement dng trong c ch xc nhn - Vng Data offset: chiu di ca Header tnh theo n v 32 bit - Mt s c (flags): . URG (Urgent): thit lp 1 khi c d liu quan trng cn truyn ngay. . ACK: cho bit c s xc nhn nm trong vng Acknowledgement . PSH (Push): c thit lp trong trng hp d liu nn c giao tc thi . RST (Reset): ch th mt li sai v hy b phin lm vic . SYN (Synchronize): trong cc bn tin khi to khi thit lp mt kt ni truyn d liu . FIN (Finish): dng ng 1 phin lm vic - Vng Window: ch ra s lng khng gian b m kh dng nhn d liu

- Vng Checksum: vng kim tra sai cho c segment - Vng Urgent Pointer: ch ra chiu di ca d liu urgent - Vng Options: xc nh kch thc cc i ca 1 segment C th hn, vai tr ca TCP trong chng giao thc TCP gm 3 chc nng chnh: iu khin lung, kim sot li v bo nhn. - iu khin lung: iu phi tc v kch thc lung d liu m bo pha nhn kh nng nhn v x l lung d liu. - Kim sot li: m bo cc gi tin n ng v - Bo nhn: khi nhn c d liu v khng c li, pha nhn phi bo li vi pha gi bit. thc hin c cc chc nng , mt qu trnh truyn d liu qua giao thc TCP (m ta gi l phin truyn thng session) gm c 3 giai on: - Thit lp kt ni - Truyn d liu - Gii ta kt ni c th hnh dung c qu trnh , mi cc bn xem minh ha sau: Thit lp kt ni:

Truyn d liu:

Gii ta kt ni:

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

c th gim st cht ch trng thi v mi s kin xy ra trong 1 kt ni TCP, trng thi ca mt kt ni TCP c chuyn i tun theo mt lu trng thi nh sau:

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

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

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

UartTxBufferStart UartTxBufferLen = UartRxBufferStart UartRxBufferLen = sei();

= 0; 0; = 0; 0;

} //------------------------------------------------------------------------------------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; }else{

//Gui luon //Cho neu

//Neu uart dang ban while(UartTxBufferLen == UART_TX_BUFFER_SIZE); buffer dang day i = UartTxBufferStart + UartTxBufferLen; UartTxBufferLen++; if(i >= UART_TX_BUFFER_SIZE) i -=UART_TX_BUFFER_SIZE; UartTxBuffer[i] = c; //Ghi vao cuoi buffer

} } //------------------------------------------------------------------------------------int printfP(const prog_char *format, ...) { // simple printf routine // define a global HexChars or use line below //static char HexChars[16] = "0123456789ABCDEF"; char c; unsigned int u_val, div_val, base; va_list ap; va_start(ap, format); for (;;) { while ((c = pgm_read_byte(format++) ) != '%') { // Until '%' or '\0' if (!c) { va_end(ap); return(0); } uartSendByte(c); } switch (c = pgm_read_byte(format++) ) { case 'c': c = va_arg(ap,int); default: uartSendByte(c); continue; case 'd': base = 10; div_val = 10000; goto CONVERSION_LOOP; // case 'x': base = 16; div_val = 0x10; case 'x': base = 16; div_val = 0x1000; CONVERSION_LOOP: u_val = va_arg(ap,int); if (c == 'd') { if (((int)u_val) < 0) { u_val = - u_val; uartSendByte('-'); } while (div_val > 1 && div_val > u_val) div_val /= 10; } do

{ //c =pgm_read_byte(HexTable+(u_val/div_val)); uartSendByte(pgm_read_byte(HexTable+(u_val/div_val))); u_val %= div_val; div_val /= base; } while (div_val); } } va_end(ap); } //-------------------------------------------------------------------------------------

Ni dung file uart.h: Code:


//--------------------------------------------------------------------------// Writen by NTTam - PTITHCM //--------------------------------------------------------------------------#ifndef UART_H #define UART_H #include <avr/pgmspace.h> //--------------------------------------------------------------------------#define UART_TX_BUFFER_SIZE 8 #define UART_RX_BUFFER_SIZE 8 //------------------------------------------------------------------------------------#ifndef UART_INTERRUPT_HANDLER #define UART_INTERRUPT_HANDLER SIGNAL #endif //define for ATmega32 register #define USR UCSRA #define UCR UCSRB #define UBRR UBRRL #define EICR EICRB #define USART_RX USART_RXC_vect #define USART_TX USART_TXC_vect //------------------------------------------------------------------------------------void uartInit(unsigned long baudrate); char uartGetByte(); void uartSendByte(char c); int printfP(const prog_char *format, ...); #define printf(format, args...) printfP(PSTR(format), ## args) //------------------------------------------------------------------------------------#endif //UART_H

Tip tc hm vo project cp file timer.c v timer.h Ni dung file timer.c: Code:


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

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

Ni dung file timer.h: Code:


//--------------------------------------------------------------------------// Writen by NTTam - PTITHCM //--------------------------------------------------------------------------#ifndef TIMER_H

#define TIMER_H //--------------------------------------------------------------------------#define TIMER_CLK_STOP 0x00 ///< Timer Stopped #define TIMER_CLK_DIV1 0x01 ///< Timer clocked at F_CPU #define TIMER_CLK_DIV8 0x02 ///< Timer clocked at F_CPU/8 #define TIMER_CLK_DIV64 0x03 ///< Timer clocked at F_CPU/64 #define TIMER_CLK_DIV256 0x04 ///< Timer clocked at F_CPU/256 #define TIMER_CLK_DIV1024 0x05 ///< Timer clocked at F_CPU/1024 #define TIMER_CLK_T_FALL 0x06 ///< Timer clocked at T falling edge #define TIMER_CLK_T_RISE 0x07 ///< Timer clocked at T rising edge #define TIMER_PRESCALE_MASK 0x07 ///< Timer Prescaler Bit-Mask #define TIMER1PRESCALE default TIMER_CLK_DIV64 ///< timer 1 prescaler

#ifndef TIMER_INTERRUPT_HANDLER #define TIMER_INTERRUPT_HANDLER #endif void timer1Init(void); void timerInit(void); #endif //TIMER_H

SIGNAL

Mc ch chnh ca timer y l ta to ra ngt ( y dng timer 1, cc bn dng timer no cng c), gi hm kim tra timeout v cp nht watchdog timer. Thm define vo ntAVRnet.h Code:
#define TIMER_PRESCALE #define TIMER1_INTERVAL 1024 (F_CPU/TIMER_PRESCALE)

#define IPDOT(a,b,c,d) ((unsigned long)((unsigned char)a)<<24)+((unsigned long)((unsigned char)b)<<16)+((unsigned long)((unsigned char)c)<<8)+(unsigned char)d//((a<<24)|(b<<16)|(c<<8)|(d)) #define IPADDRESS IPDOT(192,168,1,10) #define NETMASK IPDOT(255,255,255,0) #define GATEWAY IPDOT(192,168,1,1) #define #define #define #define #define #define ETHADDR0 ETHADDR1 ETHADDR2 ETHADDR3 ETHADDR4 ETHADDR5 '0' 'F' 'F' 'I' 'C' 'E'

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


#include "arp.h" #include "ip.h"

Thm include vo file ip.c: Code:


#include "icmp.h"

#include "uart.h"

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

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


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

printf(

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

V vit hm khi ng h thng: Code:


//------------------------------------------------------------------------------------void SystemInit() { timerInit(); uartInit(UART_BAUDRATE);

V cui cng l vit hm main(): Code:


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

Bin dch, np chip v th g lnh ping 192.168.1.10 xem sao. a ch IP, Subnet v gateway cc bn c th thay i cc define trong file ntAVRnet.h cho ph hp vi mng nh mnh nh.

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

Nn nh data l bin con tr n kiu char, v vy ta p kiu n sang bin con tr kiu int: (unsigned int *)data v ly gi tr ti a ch con tr th c s 16 bit: *((unsigned int *)data). Tip theo ta tng bin con tr thm 2 byte v tr len i 2 byte. Lp n khi no s byte cn li

nh hn 2. n y, nu s byte l chn, len=0, nu s byte l (chia tng cp 2 byte cn tha li 1 byte) th len=1. Ta cng nt byte vo (xem n nh l 1 t 2 byte m byte cao bng 0x00): Code:
if (len)//Tuc la len=1, con thua 1 byte sum += *(unsigned char *) data;

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

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

Phc tp cha. ni l khi vit phn ny ti mt 4h ch sa hm checksum v debug cc gi IP xem mnh sai ch no. Em thc mc cng khng c g l.

Lc trc ti khng m phng, m ni chung trc gi him khi no m phng trc khi lm mch, v mch phc tp th vic m phng khng c nhiu ngha, m mch n gin th cn g phi m phng, ch m phng mch analog thi. ng l ti qun mt define thng s ny, cc bn thm vo, tc ty mi ngi thi. V d: Code:
#define UART_BAURATE 9600l

Thy v mi ngi trn din n, cho hi cu ny: Em b li debug nh hnh. C kim trn mng cch sa(edit include), c sa li c kha kh, but ci thng li ny tng na l vi cc li khc, m li khng sa c. Mong mi ngi ch gip! File nh Km 35158 Li c ngha l kiu struct APentry c nh ngha 2 ln. Li ny thng pht sinh do file arp.h c include 2 ln vo 1 file code. Chnh v vy m trong mi file header, ti u thm vo u file: Code:
#ifndef ARP_H #define ARP_H

v cui file: Code:


#endif //ARP_H

Cc dng ny nhm mc ch nu file c include nhiu hn 1 ln, th cc ln sau n s c b qua (v iu kin #ifndef ARP_H s false, do ARP_H c nh ngha trc . Cn 1 l do c th dn n li ny l do khai bo trng APentry u (t c kh nng xy ra). Nu tm khng ra li, em c th gi ton b code ln D hay qua mail, ti s check cho.

bc phi post c project ln ch em debug ok ri, m m phng = proteus,hin th ln terminal ton k t Ai Cp thi, he he Xem li baudrate, set fulse cho system clock, tn s thch anh, cc define tc CPU.

Thy mi ngi build code gp nhiu vn , nn ti cng th to project theo code hng dn trn thread v buid th, xem c sai st g khng:

Ch c 1 li l thiu khai bo baudrate m bn hieppro89 ch ra. Cc bn thm khai bo ny vo file "ntAVRnet.h" nh, file ny chng ta s lu mi thng tin cu hnh chung, sau ny c th sa i d dng. Baudrate ty mi ngi quyt dch thi, thp th t sai bit hn (hin ra ch Ai Cp nu mch lm chun v tc chip set ng th t khi sai bit lm. Np th vo chip bng mch np t ch: ), nhng thc ra

Th gn cp mng vo v ping ti mch:

Vy l OK nh, code khng c sai st. Ti y th ch c vy thi v chng ta mi vit ti giao thc ICMP, tr li cho lnh ping. Cc th mm mui gia v nh LCD, ADC,... mi ngi t mnh thm vo nh. ang suy ngh xem c nn post ton b project va build ln khng, nhng kt lun l khng. V thread ny lp ra nhm gip mi ngi t mnh vit code, hay t nht cng hiu c code v modify cho ph hp vi mc ch ca mnh, t xy dng project ca mnh, khng khuyn khch "download and build"

Mi ngi thng cm nh, v mu gio vin m . Vi li ti tng gp rt nhiu bn download mch v source code trn mng v lm, khng hiu t g v mch cng nh source, nhng c bo l mnh lm c. Nu ai thc s gp kh khn v khng th t build code c, c lin h trc tip, ti sng sng gip. Cn 4 giao thc na: TCP, UDP, HTTP, v DHCP l ta c th hon thnh project ny. Do ny cng vic ngp u, cha c thi gian vit tip tut, mi ngi thng cm nh. V phi gii thch code v giao thc nn cng mt nhiu thi gian.

qun khi khai bo define cho baudrate, cc bn phi thm k t l (long) vo cui nh: Code:
#define UART_BAUDRATE 9600l

cho trnh bin dch bit l gi tr long, v trong hm khi to uart, bin tng ng l bin long.

By gi l phn code cho TCP : Ta li to 2 file source v header : tcp.c : Code:


//--------------------------------------------------------------------------// Writen by NTTam - PTITHCM //--------------------------------------------------------------------------#include "packet.h" #include "ethernet.h" #include "ip.h" #include "uart.h" #include "tcp.h"

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

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


//------------------------------------------------------------------------------------//Cau truc TCP header struct ntTCPHeader {

unsigned unsigned unsigned unsigned unsigned unsigned unsigned unsigned unsigned unsigned

int int long long char char int int int char

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

}; #define TCP_HEADER_LEN 20

nh ngha cc c (flags) trong header TCP: v khi truy xut buffer, ta ch truy xut c tng byte, sau ta da vo mask ca cc c c nh ngha y truy xut ti c tng ng. Code:
#define #define #define #define #define #define #define #define #define TCP_NON_FLAG TCP_FIN_FLAG TCP_SYN_FLAG TCP_RST_FLAG TCP_PSH_FLAG TCP_ACK_FLAG TCP_URG_FLAG TCP_ECE_FLAG TCP_CWR_FLAG (0) (1<<0) (1<<1) (1<<2) (1<<3) (1<<4) (1<<5) (1<<6) (1<<7)

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

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

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

S kt ni ng thi ti a cho php: Code:


//maximum connection count

#define TCP_MAX_SESSION 8

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


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

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

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

Tip theo l hm ng 1 phin TCP: Code:


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

Vit hm khi to cc bin cho giao thc TCP: Code:


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

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

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


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

#endif }

Hm kim tra Timeout ca cc phin TCP ang kt ni Code:


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

Hm tnh checksum cho gi TCP Code:


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

Tip theo l hai hm chnh ca giao thc: Hm gi 1 on d liu i bng giao thc TCP: Code:
//------------------------------------------------------------------------------------//Gui di mot goi TCP void TCPPackedSend(struct tcpSession *pSession, unsigned char Flags, unsigned int len, unsigned char *dataBuffer) { unsigned int tmp; unsigned long checksum32; //Make pointer to TCP header struct ntTCPHeader* tcpHeader; struct ntIPHeader* ipHeader; //Neu dang syn thi them option ve MSS if(Flags & TCP_SYN_FLAG){ //Option data dataBuffer[0] = 0x02; dataBuffer[1] = 0x04; dataBuffer[2] = (MAX_SEGMENT_SIZE >> 8) & 0xff; dataBuffer[3] = MAX_SEGMENT_SIZE & 0xff; dataBuffer[4] = 0x01; dataBuffer[5] = 0x03; dataBuffer[6] = 0x03; dataBuffer[7] = 0x00; //Move data pointer to make room for TCP header } dataBuffer -= TCP_HEADER_LEN; tcpHeader = (struct ntTCPHeader*)dataBuffer; //Fill UDP header tcpHeader->srcPort = HTONS(pSession->srcPort); tcpHeader->desPort = HTONS(pSession->desPort); tcpHeader->seqNumber = HTONL(pSession->seqNumber); pSession->seqNumber = pSession->seqNumber + len; if(Flags & (TCP_FIN_FLAG|TCP_SYN_FLAG)) (pSession->seqNumber)++; tcpHeader->ackNumber = HTONL(pSession->ackNumber); if(Flags & TCP_SYN_FLAG){ tcpHeader->Offset = (0x07<<4); len += (TCP_HEADER_LEN + 8); }else{ tcpHeader->Offset = (0x05<<4); len += TCP_HEADER_LEN; } tcpHeader->Flags = Flags; tcpHeader->Window = HTONS(pSession->srcWin);//((NETSTACK_BUFFERSIZE20-14)); tcpHeader->Checksum = 0; tcpHeader->UrgentPtr = 0x0000; //Generate checksum ipHeader = (struct ntIPHeader*)(dataBuffer-IP_HEADER_LEN); ipHeader->srcIPAddr = HTONL(ipGetConfig()->ip); ipHeader->desIPAddr = HTONL(pSession->desIP); ipHeader->Checksum = HTONS(len); ipHeader->TTL = 0x00;

ipHeader->Protocol = IP_PROTO_TCP; checksum32 = 0; tmp = len + 12; tmp = checksum (((unsigned char *)ipHeader+8), tmp, checksum32); tcpHeader->Checksum = HTONS(tmp); ipSend(pSession->desIP, IP_PROTO_TCP, len, (unsigned char *)tcpHeader); }

Hm x l khi nhn c 1 gi TCP Code:


//------------------------------------------------------------------------------------//Ham xu ly goi TCP nhan duoc, duoc goi boi giao thuc IP (IPProcess) void TCPProcess(unsigned char *buffer, unsigned int len) //Ham xu ly cho giao thuc TCP // Duoc thuc thi khi nhan duoc mot goi TCP (goi boi netstackIPProcess) // buffer: co tro den dau goi IP (bat dau IP Header) // len : chieu dai buffer { unsigned char i,ipHeaderLen,tcpHeaderLen; unsigned int dataLen; unsigned long tmp; struct ntIPHeader* ipHeader; struct ntTCPHeader* tcpHeader; unsigned char *tcpData; //Khoi tao cac co tro den Header IP va TCP ipHeader = (struct ntIPHeader*)(buffer); ipHeaderLen = ((ipHeader->verHdrLen) & 0x0F) << 2; // tcpHeader = (struct ntTCPHeader*)(buffer+ipHeaderLen); tcpHeaderLen = ((tcpHeader->Offset) & 0xF0) >> 2; // tcpData = (buffer+ipHeaderLen+tcpHeaderLen); dataLen = HTONS(ipHeader->Len) - (ipHeaderLen + tcpHeaderLen); //Tim kiem mot phien TCP co san cho goi nay for(i = 0; i < TCP_MAX_SESSION; i++){ //Check session table if(tcpSessionTable[i].sesState != TCP_STATE_CLOSED){ //If not closed session if(tcpSessionTable[i].srcPort == HTONS((tcpHeader>desPort))){ //If matched local port if(tcpSessionTable[i].desPort == HTONS((tcpHeader->srcPort))&&(tcpSessionTable[i].desIP == HTONL((ipHeader>srcIPAddr)))){ break; //Thoat khoi vong lap for, luc nay gia tri cua i chinh la chi so cua phien TCP tuong ung } } } } if(i == TCP_MAX_SESSION){ //Neu khong co 1 phien TCP dang ton tai cho goi nay //Tim 1 phien dang o trang thai LISTEN (doi ket noi) cho local port nay for(i=0; i < TCP_MAX_SESSION; i++){ if(tcpSessionTable[i].sesState == TCP_STATE_LISTEN){

if(tcpSessionTable[i].srcPort == HTONS((tcpHeader->desPort))){ //If matched local port //Cap nhat remote port va remote IP tcpSessionTable[i].desPort = HTONS((tcpHeader->srcPort)); tcpSessionTable[i].desIP = HTONL((ipHeader->srcIPAddr)); //Dong thoi tao ra 1 session moi de cho ket noi khac den local port nay TCPCreateSession(tcpSessionTable[i].srcPort,tcpSessionTable[i].appData In); break; } } } } if(i == TCP_MAX_SESSION){ #ifdef TCP_DEBUG printf("No TCP session found\r\n"); #endif return; //Neu khong co phien TCP nao danh cho goi nay thi thoat ra } #ifdef TCP_DEBUG printf("TCP session found: %d\r\n",i); #endif //Bat dau xu ly giao thuc tcpSessionTable[i].timeOut = TCP_TIMEOUT; out //Truong hop nhan duoc yeu cau reset lai ket noi if ((tcpHeader->Flags) & TCP_RST_FLAG){ //Chap nhan dong ket noi TCPCloseSession(i); return; } //Kiem tra trang thai hien tai cua phien TCP switch (tcpSessionTable[i].sesState){ //Neu la trang thai doi ket noi: TCP_STATE_LISTEN case(TCP_STATE_LISTEN): //Chi xu ly neu co SYN duoc set (yeu cau thiet lap ket noi) if ((tcpHeader->Flags) == TCP_SYN_FLAG){ //Chuyen sang trang thai ke tiep la TCP_STATE_SYN_RECEIVED tcpSessionTable[i].sesState = TCP_STATE_SYN_RECEIVED; //Khoi tao gia tri sequence tcpSessionTable[i].seqNumber = HTONL(TCPInitSequenceNumber()); //Ack chinh la so tuan tu nhan duoc cong 1 tcpSessionTable[i].ackNumber = HTONL((tcpHeader->seqNumber))+1; tcpSessionTable[i].desWin = HTONS((tcpHeader>Window)); //Goi tra xac nhan va co SYN (SYN & ACK)

//Reset lai gia tri Time

TCPPackedSend(&tcpSessionTable[i],(TCP_SYN_FLAG|TCP_ACK_FLAG),0,tcpDat a); //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,tcpDat a); //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 - (n-k)) tmp = (tcpSessionTable[i].ackNumber - tmp); //Neu doan du lieu thua it hon du lieu nhan duoc if(tmp < dataLen){ //Bo di phan du lieu thua, nhan phan con lai tcpData += tmp; dataLen = dataLen - tmp; }else{ //Neu tat ca du lieu nhan duoc deu thua

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

TCPCloseSession(i); }else{ //Gui lai co FIN & ACK TCPPackedSend(&tcpSessionTable[i], (TCP_FIN_FLAG|TCP_ACK_FLAG), 0, tcpData); } break; //Truong hop ngat ket noi thu dong, da nhan co FIN tu remote host va xac nhan case(TCP_STATE_CLOSE_WAIT): //Truong hop nay se khong xay ra vi o tren ta chuyen truc tiep // sang LAST_ACK khi nhan duoc yeu cau dong ket noi tcpSessionTable[i].sesState = TCP_STATE_LAST_ACK; if(dataLen){ tcpSessionTable[i].ackNumber = HTONL((tcpHeader->seqNumber)) + dataLen; }else{ //Neu dataLen == 0 thi cung tang so tuan tu len 1 tcpSessionTable[i].ackNumber = HTONL((tcpHeader->seqNumber))+1; } //tcpSessionTable[i].seqNumber = HTONL((tcpHeader>ackNumber)); TCPPackedSend(&tcpSessionTable[i], (TCP_FIN_FLAG|TCP_ACK_FLAG), 0, tcpData); break; //Truong hop dang o trang thai FIN WAIT 1 (da truyen du lieu xong, // san sang dong ket noi va da gui di co FIN va dang cho ACK) case(TCP_STATE_FIN_WAIT1): //if we receive FIN tcpSessionTable[i].ackNumber = HTONL((tcpHeader>seqNumber))+1; if (tcpHeader->Flags == TCP_FIN_FLAG){ //Neu chi nhan duoc co FIN //Chuyen sang trang thai CLOSING va gui ACK tcpSessionTable[i].sesState = TCP_STATE_CLOSING; TCPPackedSend(&tcpSessionTable[i], (TCP_ACK_FLAG), 0, tcpData); //tcpSessionTable[i].seqNumber++; #ifdef TCP_DEBUG printf("Closing\n\r"); #endif }else if(tcpHeader->Flags == (TCP_FIN_FLAG | TCP_ACK_FLAG)){ //Neu nhan dong thoi FIN va ACK //Chuyen sang trang thai TIME_WAIT va gui ACK // nhung o day do chua co timer nen ta chuyen luon sang dong ket noi if (HTONL((tcpHeader->ackNumber)) == tcpSessionTable[i].seqNumber){ //TCPPackedSend(&tcpSessionTable[i], (TCP_ACK_FLAG), 0, tcpData); TCPCloseSession(i); #ifdef TCP_DEBUG

printf("End\n\r"); #endif }else{ //Neu khong dung ack cho thong bao FIN //Chuyen sang cho co ACK cuoi cung tcpSessionTable[i].sesState = TCP_STATE_LAST_ACK; #ifdef TCP_DEBUG printf("Last ack\n\r"); #endif } //Gui xac nhan cho co FIN TCPPackedSend(&tcpSessionTable[i], (TCP_ACK_FLAG), 0, tcpData); //tcpSessionTable[i].seqNumber++; }else if(tcpHeader->Flags == TCP_ACK_FLAG){ 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, // 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); phia ben kia da xac nhan nhung van chua san sang dong ket //Neu chi

} //we must set timed wait TTL here because timed wait is not packet triggered if (tcpSessionTable[i].sesState == TCP_STATE_TIMED_WAIT){ tcpSessionTable[i].timeOut = 5; //5 seconds timeout } return; } //-------------------------------------------------------------------------------------

Hai hm ny khip qu, nhn v thy oi ri, t t gii thch, khng hiu sao hi xa mnh li vit phc tp nh vy. Hay l mi ngi c t t nghin cu, ch no khng hiu th c hi . Gi ngh ti vit gii thch cho code thy nn qu. Vit gii thch cho code c khi cn kh hn vit code .

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

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

Sau to file source v header tng ng: udp.c Code:


//--------------------------------------------------------------------------// Writen by NTTam - PTITHCM //--------------------------------------------------------------------------#include "packet.h" #include "ip.h" #include "uart.h"

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

Ta ch vit 2 hm cho giao thc UDP: Hm gi gi tin bng UDP: Code:


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

Hm x l gi tin nhn c: Code:


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

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

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

Gii thch cho 2 hm chnh trong giao thc TCP: Hm TCPPackedSend: Code:
void TCPPackedSend(struct tcpSession *pSession, unsigned char Flags, unsigned int len, unsigned char *dataBuffer)

Trong ny: - pSession l con tr, tr n struct tcpSession trong bng TCP Session Table tng ng vi phin kt ni TCP m ta mun gi gi tin i (trong phn lp trnh giao thc TCP ny, ta h tr vic AVR ng thi theo di v truyn data vi nhiu kt ni (nhiu client) cng lc).

- Flags l cc c tng ng m ta mun set trong header TCP - len: chiu di buffer d liu ng dng. - dataBuffer: buffer cha d liu ng dng. Cu trc frame d liu m ENC28J60 s gi i nh sau:

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

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

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

By gi ta dch lui con tr dataBuffer 1 on bng chiu di TCP Header v tr tcpHeader n phn u on ny. Code:
dataBuffer -= TCP_HEADER_LEN; tcpHeader = (struct ntTCPHeader*)dataBuffer;

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

- S tun t cng vy:

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

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


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

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

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

Nu c c SYN, nh ni trn Header TCP s c trng Option chiu di 8 byte, do ta phi ghi gi tr tng ng cho trng Offset, v tng bin len ln tng ng: Code:
if(Flags & TCP_SYN_FLAG){ tcpHeader->Offset = (0x07<<4); len += (TCP_HEADER_LEN + 8);

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


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

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

Gi tr trng Window Code:


tcpHeader->Window = HTONS(pSession->srcWin);//((NETSTACK_BUFFERSIZE20-14));

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


tcpHeader->Checksum = 0;

Con tr khn khng s dng: Code:


tcpHeader->UrgentPtr = 0x0000;

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


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

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


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

y cc bn cn tm hiu thm cch tnh checksum TCP, n khng ch tnh checksum phn TCP Header v d liu m cn tnh thm 1 s trng ca IP trong 1 header IP gi, do ta phi

gn tm cc trng ny ln buffer th mi tnh c TCP checksum, cn tht ra Header IP xung giao thc IP s c xy dng li (hm ipSend). Tnh checksum v ghi vo trng checksum ca Header TCP Code:
checksum32 = 0; tmp = len + 12; tmp = checksum (((unsigned char *)ipHeader+8), tmp, checksum32); tcpHeader->Checksum = HTONS(tmp);

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


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

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

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

Sau khi c c a ch IP ngun ca host gi v port ngun, port ch, ta tm kim trong TCP session table phin TCP c sn tng ng vi gi tin ny, nu cha tn ti th khi to session mi: Code:
if(i == TCP_MAX_SESSION){ //Neu khong co 1 phien TCP dang ton tai cho goi nay //Tim 1 phien dang o trang thai LISTEN (doi ket noi) cho local port nay for(i=0; i < TCP_MAX_SESSION; i++){ if(tcpSessionTable[i].sesState == TCP_STATE_LISTEN){ if(tcpSessionTable[i].srcPort == HTONS((tcpHeader->desPort))){ //If matched local port //Cap nhat remote port va remote IP tcpSessionTable[i].desPort = HTONS((tcpHeader->srcPort)); tcpSessionTable[i].desIP = HTONL((ipHeader->srcIPAddr));

//Dong thoi tao ra 1 session moi de cho ket noi khac den local port nay TCPCreateSession(tcpSessionTable[i].srcPort,tcpSessionTable[i].appData In); 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; out //Reset lai gia tri Time

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


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

Tip theo, ta phi x l theo lu trng thi ca TCP. Ta dng 1 cu trc switchcase x l ty vo trng thi hin ti ca kt ni: Code:
switch (tcpSessionTable[i].sesState){ //Neu la trang thai doi ket noi: TCP_STATE_LISTEN case(TCP_STATE_LISTEN): break; //Neu la trang thai TCP_STATE_SYN_RECEIVED case(TCP_STATE_SYN_RECEIVED): break; //Truong hop ket noi da duoc thiet lap case(TCP_STATE_ESTABLISHED): break; //Neu la trang thai doi LAST_ACK (2 phia deu san sang dong ket noi, dang doi xac nhan ack cuoi cung) case(TCP_STATE_LAST_ACK): break; //Truong hop ngat ket noi thu dong, da nhan co FIN tu remote host va xac nhan case(TCP_STATE_CLOSE_WAIT): break; //Truong hop dang o trang thai FIN WAIT 1 (da truyen du lieu xong,

// san sang dong ket noi va da gui di co FIN va dang cho ACK) case(TCP_STATE_FIN_WAIT1): break; //Neu dang o trang thai FIN WAIT 2 (san sang dong ket noi va gui co FIN, // noi case(TCP_STATE_FIN_WAIT2): break; case(TCP_STATE_TIMED_WAIT): break; case(TCP_STATE_CLOSING): break; default: TCPCloseSession(i); } phia ben kia da xac nhan nhung van chua san sang dong ket

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

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

+ DHCPREQUEST: Client chn mt DHCP offer, to mt gi DHCP request v qung b gi ny. Gi DHCP request ny bao gm a ch IP ca server pht ra DHCP offer v a ch vt l ca DHCP client. DHCP request ny thc hin hai vic: . Bo cho DHCP server c chn rng n yu cu mt a ch IP.

. Thng bo cho cc DHCP server khc l DHCP offer ca chng khng c chp nhn.

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

em cng ang lm v pic18 +enc28j60 em bin dch chng trnh demo ca microchip th ok. nhng khi em to 1 project khc v copy ton b code ca microchip sang th khi bin dch n li mc li

nh ny: Error [1027] unable to locate 'TCPIP Stack/TCPIP.h' ti sao ci file "TCPIP Stack/TCPIP.h" ko c trong khi mi file *.h trong Microchip stack u include n ht. khi dch bn demo th li c m khi t to 1 project mi th khi dch li bo li : Error [1027] unable to locate 'TCPIP Stack/TCPIP.h' cm n thy! p/s:nu c sai toppic th mi ngi thng cm nh v nu ai m lm vi pic + enc28j60 cng s mc li ny File "TCPIP.h" nm trong th mc "Include/TCPIP Stack/" cng vi cc file header khc m. C th l em chp thiu th mc Include hoc khng ch nh th mc cha Header (Include Diectory) cho Project mi thi.

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

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

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

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


//--------------------------------------------------------------------------/// BOOTP Header struct ntBootpHeader { unsigned char opcode; //Message op-code / message type unsigned char hwaddrtype; //Hardware address type (Ethernet=1) unsigned char hwaddrlen; //Hardware address length (Ethernet=6 byte MAC addr) unsigned char hops; //hop count (client set to zero) unsigned long transid; //Transaction ID (randomly chosen by client, must remain same) unsigned int secs; //Seconds elapsed since DHCP negotiation began (filled by client) unsigned int flags; //Flags unsigned long clipaddr; //Client IP address (filled only if already bound, renewing, or rebinding) unsigned long yoipaddr; //Your IP address (client) unsigned long seipaddr; //Server IP address unsigned long gwipaddr; //Gateway IP address unsigned char clhwaddr[16]; //Client Hardware Address unsigned char sename[64]; //Server Host Name unsigned char file[128]; //Boot file name (null-term string) }; //

#define BOOTP_HEADER_LEN 236 //length of BOOTP header not including options // #define BOOTP_OP_BOOTREQUEST 1 //BOOTP Request operation (message from client to server) #define BOOTP_OP_BOOTREPLY 2 //BOOTP Reply operation (message from server to client) // #define BOOTP_HTYPE_ETHERNET 1 //Hardware type for ethernet protocol #define BOOTP_HLEN_ETHERNET 6 //Length of ethernet MAC address //--------------------------------------------------------------------------struct netDhcpHeader { struct ntBootpHeader bootp; //BOOTP header unsigned long cookie; //magic cookie value unsigned char options[1]; //DHCP options }; // #define DHCP_HEADER_LEN 240 //length of DHCP header not including options

Tip theo ta nh ngha 1 s gi tr hng c qui nh cho cc trng trong header: Code:
//Code for DHCP option field #define DHCP_OPT_PAD skipped) #define DHCP_OPT_NETMASK (4 byte mask) #define DHCP_OPT_ROUTERS addr list) #define DHCP_OPT_TIMESERVERS addr list) #define DHCP_OPT_NAMESERVERS addr list) #define DHCP_OPT_DNSSERVERS (IP addr list) #define DHCP_OPT_HOSTNAME (string) #define DHCP_OPT_DOMAINNAME (string) #define DHCP_OPT_REQUESTEDIP address) #define DHCP_OPT_LEASETIME seconds) #define DHCP_OPT_DHCPMSGTYPE #define DHCP_OPT_SERVERID #define DHCP_OPT_PARAMREQLIST #define DHCP_OPT_RENEWALTIME seconds) #define DHCP_OPT_REBINDTIME (uint32 seconds) #define DHCP_OPT_CLIENTID #define DHCP_OPT_END options list) //Code for DHCP message type 0 1 3 4 5 //token padding value (make be //subnet mask client should use //routers client should use (IP

//time servers client should use (IP //name servers client should use (IP 6 12 15 //DNS servers client should use //host name client should use //domain name client should use

50

//IP address requested by client (IP 51 //DHCP Lease Time (uint32

53 55 58

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

61 //DHCP Client Identifier 255 //token end value (marks end of

#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 be sent #define replies // #define #define DHCP_UDP_SERVER_PORT DHCP_UDP_CLIENT_PORT DHCP_TIMEOUT DHCP_RETRIES 10 3 67 68 //UDP port where DHCP requests should //UDP port clients will receive DHCP

By gi ta m file source v bt u vit code: Trc ht ta khai bo cc bin s dng : Code:


//------------------------------------------------------------------------------------unsigned long DhcpServerIP; unsigned long DhcpTransactID; unsigned long DhcpLeaseTime; unsigned char macaddr[6]; // unsigned char DhcpTimeout; unsigned char DhcpRetries;

Vit hm khi to giao thc DHCP: Code:


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

Hm ghi gi tr vo trng option ca DHCP, mi trng option s bt u bng 1 byte option code, tip n l 1 byte chiu di ca gi tr option, theo sau l cc byte gi tr ca option:

Code:
//------------------------------------------------------------------------------------//Ham set cac option cua DHCP unsigned char* dhcpSetOption(unsigned char* options, unsigned char optcode, unsigned char optlen, void* optvalptr) { *options++ = optcode; *options++ = optlen; while(optlen--) { *options++ = *(unsigned char*)optvalptr++; } *options = DHCP_OPT_END; return options; }

Hm c gi tr t trng option vo 1 bin: Code:


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

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


//------------------------------------------------------------------------------------#ifdef DHCP_DEBUG //Ham de in Header goi DHCP (de debug) void dhcpPrintHeader(struct netDhcpHeader* packet) {

printf("DHCP Packet:\r\n"); // print op printf("Op : "); switch(packet->bootp.opcode) { case BOOTP_OP_BOOTREQUEST: case BOOTP_OP_BOOTREPLY: default: break;

printf("BOOTREQUEST"); break; printf("BOOTREPLY"); break; printf("UNKNOWN");

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

Hm gi i bn tin DHCP discover : Code:


//------------------------------------------------------------------------------------//Ham gui di mot ban tin DHCP discover de tim kiem DHCP server void dhcpDiscover(void) { struct netDhcpHeader* packet; unsigned long val; unsigned char* optptr; packet = (struct netDhcpHeader*)(ethGetBuffer() + ETH_HEADER_LEN + IP_HEADER_LEN + UDP_HEADER_LEN); // packet->bootp.opcode = BOOTP_OP_BOOTREQUEST; packet->bootp.hwaddrtype = BOOTP_HTYPE_ETHERNET; packet->bootp.hwaddrlen = BOOTP_HLEN_ETHERNET; packet->bootp.clipaddr = HTONL(ipGetConfig()->ip); packet->bootp.yoipaddr = HTONL(0l); packet->bootp.seipaddr = HTONL(0l); packet->bootp.gwipaddr = HTONL(0l); ethGetMacAddress(&packet->bootp.clhwaddr[0]); packet->bootp.transid = DhcpTransactID; packet->bootp.flags = HTONS(1); // packet->cookie = 0x63538263;

val = DHCP_MSG_DHCPDISCOVER; optptr = dhcpSetOption(packet->options, DHCP_OPT_DHCPMSGTYPE, 1, &val); dhcpSetOption(optptr, DHCP_OPT_CLIENTID, 6, macaddr); #ifdef DHCP_DEBUG printf("DHCP: Sending Query\r\n"); dhcpPrintHeader(packet); #endif udpSend(0xFFFFFFFF, DHCP_UDP_SERVER_PORT, DHCP_UDP_CLIENT_PORT, DHCP_HEADER_LEN+3+1+8, (unsigned char*)packet); }

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


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

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


//------------------------------------------------------------------------------------//Ham xu ly mot goi DHCP nhan duoc void dhcpIn(unsigned int len, struct netDhcpHeader* packet) { unsigned char msgtype; unsigned long sid; unsigned long netmask; unsigned long gateway; unsigned long val; // #ifdef DHCP_DEBUG dhcpPrintHeader(packet);

#endif // if((packet->bootp.opcode != BOOTP_OP_BOOTREPLY) || (packet>bootp.transid != DhcpTransactID)) return; // dhcpGetOption(packet->options, DHCP_OPT_DHCPMSGTYPE, 1, &msgtype); #ifdef DHCP_DEBUG printf("DHCP: Received msgtype = %d\r\n", msgtype); #endif // if(msgtype == DHCP_MSG_DHCPOFFER) { dhcpGetOption(packet->options, DHCP_OPT_SERVERID, 4, &sid); #ifdef DHCP_DEBUG printf("DHCP: Got offer from server "); ipPrintAddr(HTONL(sid)); printf("\n\r"); #endif dhcpRequest(packet, sid); } // else if(msgtype == DHCP_MSG_DHCPACK) { dhcpGetOption(packet->options, DHCP_OPT_NETMASK, 4, &val); netmask = HTONL(val); // dhcpGetOption(packet->options, DHCP_OPT_ROUTERS, 4, &val); gateway = HTONL(val); // dhcpGetOption(packet->options, DHCP_OPT_LEASETIME, 4, &val); DhcpLeaseTime = HTONL(val); // ipSetConfig(HTONL(packet->bootp.yoipaddr), netmask, gateway); // DhcpRetries = 0; #ifdef DHCP_DEBUG printf("DHCP: Got request ACK, bind complete\r\n"); ipPrintConfig(ipGetConfig()); printf("LeaseTm : %d\n\r", DhcpLeaseTime); #endif } }

Hm hy b a ch IP hin ti: Code:


//------------------------------------------------------------------------------------//Ham release dia chi IP hien tai va xoa cac thong so cau hinh IP dang co void dhcpRelease(void) { struct netDhcpHeader* packet; unsigned long val; unsigned char* optptr; // packet = (struct netDhcpHeader*)&ethGetBuffer()[ETH_HEADER_LEN+IP_HEADER_LEN+UDP_HEADER_LEN]; //

packet->bootp.opcode = BOOTP_OP_BOOTREQUEST; packet->bootp.hwaddrtype = BOOTP_HTYPE_ETHERNET; packet->bootp.hwaddrlen = BOOTP_HLEN_ETHERNET; packet->bootp.clipaddr = HTONL(ipGetConfig()->ip); packet->bootp.yoipaddr = HTONL(0l); packet->bootp.seipaddr = HTONL(0l); packet->bootp.gwipaddr = HTONL(0l); ethGetMacAddress(&packet->bootp.clhwaddr[0]); packet->bootp.transid = DhcpTransactID; packet->bootp.flags = HTONS(1); // packet->cookie = 0x63538263; // val = DHCP_MSG_DHCPRELEASE; optptr = dhcpSetOption(packet->options, DHCP_OPT_DHCPMSGTYPE, 1, &val); // val = HTONL(DhcpServerIP); optptr = dhcpSetOption(optptr, DHCP_OPT_SERVERID, 4, &val); // optptr = dhcpSetOption(optptr, DHCP_OPT_REQUESTEDIP, 4, &packet>bootp.clipaddr); // #ifdef DHCP_DEBUG printf("DHCP: Sending Release to "); ipPrintAddr(DhcpServerIP); printf("\n\r"); #endif udpSend(DhcpServerIP, DHCP_UDP_SERVER_PORT, DHCP_UDP_CLIENT_PORT, DHCP_HEADER_LEN+3+6+6+1, (unsigned char*)packet); ipSetConfig(0,0,0); DhcpLeaseTime = 0; }

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


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

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


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

DhcpTimeout = DHCP_TIMEOUT; dhcpDiscover(); } } //-------------------------------------------------------------------------------------

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

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

2-M file udp.c, sa hm udpSend b sung source port vo trong hm, thm lnh gi hm ca giao thc DHCP vo hm UDPProcess: Code:
//--------------------------------------------------------------------------// Writen by NTTam - PTITHCM //--------------------------------------------------------------------------#include "packet.h" #include "ip.h" #include "uart.h" #include "dhcp.h" //#define UDP_DEBUG //--------------------------------------------------------------------------//Ham gui di mot goi UDP void udpSend(unsigned long dstIp, unsigned int dstPort, unsigned int srcPort, unsigned int len, unsigned char* udpData) { struct ntUDPHeader* udpHeader; udpHeader = (struct ntUDPHeader*)(udpData - UDP_HEADER_LEN); len += UDP_HEADER_LEN; udpHeader->desPort = HTONS(dstPort); udpHeader->srcPort = HTONS(srcPort); udpHeader->Len = HTONS(len); udpHeader->Checksum = 0; ipSend(dstIp, IP_PROTO_UDP, len, (unsigned char*)udpHeader); } //------------------------------------------------------------------------------------//Ham xu ly goi UDP nhan duoc, duoc goi boi ham xu ly goi IP (IPProcess) // Hien chua co ung dung chay UDP nen ham nay trong void UDPProcess(unsigned int len, struct ntIPHeader* packet) { dhcpIn((len - IP_HEADER_LEN - UDP_HEADER_LEN), (struct netDhcpHeader*)((char*)packet + IP_HEADER_LEN + UDP_HEADER_LEN));

#ifdef UDP_DEBUG printf("Rx UDP Packet\r\n"); #endif } //-------------------------------------------------------------------------------------

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

printf("IP->Rx: IP packet\r\n"); #endif } } //-------------------------------------------------------------------------------------

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

6-Thm vo hm main trong file ntAVRnet.h Code:


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

By gi nu lc u mch ca ta cha c a ch IP (IP address l 0.0.0.0) th n s khi to giao thc DHCP nhn a ch IP. th, ta chnh li cc thng s cu hnh IP trong file ntAVRnet.h nh sau: Code:
#define IPDOT(a,b,c,d) ((unsigned long)((unsigned char)a)<<24)+((unsigned long)((unsigned char)b)<<16)+((unsigned long)((unsigned char)c)<<8)+(unsigned char)d//((a<<24)|(b<<16)|(c<<8)|(d)) //#define IPADDRESS IPDOT(192,168,1,10) #define IPADDRESS IPDOT(0,0,0,0) #define NETMASK IPDOT(0,0,0,0) #define GATEWAY IPDOT(0,0,0,0)

By gi ta c th bin dch, ni cp mng v m ngun, i board nhn a ch IP (nh kt ni cng COM cn bit n nhn c a ch bao nhiu nh). Phn code ny ch khi ng DHCP lc mi reset mch thi nh, cha h tr hot plug cp mng . Cc bn c th t sa code thm phn ny vo.

TCP/IP stack???
Bn cha ch nh th mc cha file header cho project thi: Vo menu project->Build options->Projects: chn tab dectories, chn "Include search path" ri add cc th mc c cha file header vo (c Header ca TCPIP stack v cc file header ca chng trnh. Vo menu project->Build options->Projects, chnh nh sau (thm 2 dng vo vo v chn ty chn Asemble/... th hai):

S cn pht sinh 1 li khc nhng l do khai bo chip s dng ca bn thi.

Nguyn vn bi nttam79 Vo menu project->Build options->Projects, chnh nh sau (thm 2 dng vo vo v chn ty chn Asemble/... th hai): S cn pht sinh 1 li khc nhng l do khai bo chip s dng ca bn thi. hc ng nh thy d bo,sa c li trn th li xut hin li tip theo.( Error [1099] Invalid MAX_TCP_SOCKETS value specified ) nhiu li vy th lm sao m c gi l bn demo hay open code.microchip ng l nh ngi ta qu mun tm 1 bn mu load vo PIC xem demo th m kh khn tht.

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 }

Anh Tm c hi " Trong hm ArpIpOut trn, c 1 ch "lch lut", khng tun th ng nguyn tc lm vic ca ARP, cc bn tm ra, nu c ai tm ra mnh s gii thch ti sao li lm nh vy." Hm nay mi c code ca anh Tm vit v n y thy anh Tm hi rt hay nn tm hiu v tr li th ny, c g anh Tm chnh nha. - Trong hm ArpIpOut d tm a ch MAC ng vi IP trong bng ARP cache m thng IP n hi. Nu trong bng ARP cache ( bng ny <=8 trong project) khng c IP tng ng, hay bng ARP cache cha c cp nht y th theo cch gii quyt ca giao thc ARP l n s gi i mt gi tin c tn l ARP request cha IP m n cn tm di dng broadcast trong mng LAN "Ai l ngi c a ch IP a.b.c.d ?" my tnh no c a ch IP trn s tr li bng bn tin ARP reply. - Tuy nhin trong code ca anh Tm th ARP khng gi gi tin ARP request m in lun a ch

MAC ch l FF.FF.FF.FF.FF.FF vo trong gi IP, v l d nhin l gi tin ny s gi n tt c cc my trong mng LAN nhng thng no c IP ng th mi nhn c v giao thc IP s kim tra li IP gi c gi ti c phi l ca mnh hay khng. - Nh chng ta bit bng ARP cache c cp nht l c 2 trng hp. 1- l gi bn tin ARP request, 2- mi khi c gi tin IP n th n s cp nht IP v MAC ca thng my tnh gi i. C nh th nu thng no gi th n s t cp nht IP v MAC vo bng ARP cache thi. Khng bit Huy ni th c ng khng na v g m. Hehe c g anh Tm chnh li em nh. Thanks!
Huy tm ra rt ng ch, rptdnmqs cng tm ra nhng cha ni ng nguyn nhn phi lm nh vy. L do phi lm vy l: khi giao thc IP nhn c yu cu gi gi tin i th d liu ng dng nm sn trn buffer dnh cho frame ethernet ri (ethFrame). Lc ny mun gi i bn tin ARP request theo "ng lut", ta phi to ra mt buffer mi cho bn tin ARP request s gi i, v nu khng s ghi ln d liu ng dng. Nhng b nh RAM ca ATmega 32 nh qu (c 2K) nn khng ch, v vy buc phi "lch lut" thi, hehe.

Nguyn vn bi kiemkhach10 anh tam sa gip em nt ci li ny vi. em c th c bn dch demo c th chy c li l: :Error [1099] Invalid MAX_TCP_SOCKETS value specified. y l project em ang sa n li : down:pic18f4620.402-fix.rar cm n anh nhiu! C sa li th s li c li khc thi, quan trng l bn phi sa li cc define trong HardwareProfile v cc file config c lin quan cho ph hp vi hardware ca mnh, nu khng c bin dch thnh cng th np vo mch cng khng chy. Nu bn ch mun bin dch c 1 ci cho c kh th tip tc th c th sa cc define nh sau: thm vo TCPIPconfig.h: Code:
#define #define #define #define #define MAX_TCP_SOCKETS (8ul) TCP_TX_FIFO_SIZE (200ul) TCP_RX_FIFO_SIZE (200ul) MAX_UDP_SOCKETS (8ul) MAX_HTTP_CONNECTIONS (3ul) "OLIMEX BOARD" (0x00) (94ul)

#define MY_DEFAULT_HOST_NAME #define MY_DEFAULT_MAC_BYTE6 #define MY_DEFAULT_IP_ADDR_BYTE4

Thm vo HardwareProfile.h: Code:


#define OLIMEX_HW

Chc thnh cng

Anh Tm cho em hi ci ny na: 1- Nu mnh set 2 mch cng MAC cng IP th s xy ra chuyn g nh. 2- Em np chng trnh vo mch ti on m Ping c nh hm trc (em dng cp cho cm trc tip t Board n my tnh), lc mi cm in vo mch Ping th OK nhng mt lc nh mnh lt web hay lm ci g lin quan n internet trn my tnh th Ping li khng c na mc d nhn nt reset cng trn mch. Li ny l do trn b nh ENC hay treo chng trnh VK h anh. 1- Nu 2 mch set cng a ch MAC v IP th khi gi n a ch IP ny, c 2 mch cng nhn c, cc host khc s xem nh ch bit c 1 mch trn LAN. Tuy nhin khi hot ng s xy ra li: v khi 1 my khc truy cp theo a ch , hai mch s cng tr li, iu ny s c th dn n giao thc TCP s khng thit lp kt ni c do my tnh truy cp s nhn c nhiu bn tin SYN (v c th c s sequence number khc nhau nu ta dng c ch nh sequence number theo thi gian). Kt qu l khng truy cp webserver c. 2-Thnh thong anh cng nhn thy hin tng ny v debug th nhng cha tm ra l do. C th do chip ENC treo hoc do ta qun l b nh AVR cha tt. Nh lc vit giao thc ethernet anh c ni l s dng bin watchdog timer reset ENC mi khi n b treo, dng gii php ny s khc phc c tnh trng , mch chy n nh hn rt nhiu. Nhng th thc l anh cha tm ra c ngun gc ca vn . C l phi dnh tg tm hiu phn cng ENC28J60 v debug th mi bit c. Nu c thi gian Huy th nghin cu vn ny xem th nh.

cm n anh! trong phn #define c my ci (8ul),(200ul)... ngha l g nh?v ul c ngha l g nh? cm n! ul = unsigned long ci ny ch c ngha gip trnh bin dch (complier) tnh ton ng khi bin dch, khng phi l khai bo kiu bin.

p/s: bc no cho em hi thm con ic 28j60 y: +chn s 3 ( l chn CLOCK OUT) c tc dng g? +chn s 5 (l chn WOL) c tc dng g? +chn s 10(l chn reset) th reset mc cao hay thp hay khi no rs? vy trong 3 chn ny c th b chn no ko dng ko? cm n cc bc! Bn xem li xem, ch thay bnh thng m, ch sao cho string khng vt qu 16 k t thi. Hay bn copy thng bo li ln th mi bit c. Chn CLOCK OUT cho php xut xung clock t ENC28J60 (25MHz) vi cc h s chia lp trnh c (1,2,3,4,8)

WOL=Wake up On LAN, 1 chc nng cho php kch hot thit b t trng thi standby khi c hot ng trn mng LAN, nhng lu l chc nng ny trn ENC28J60 cha c nh, ch cha sn chn ny thi. Chn reset tch cc mc thp. 3 chn ny c th b c ht, nhng nh ko reset ln thi.

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

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

a-Simple-Request: c cu trc rt n gin GET<space><Request-URI><CRLF> b-Full-Request: c cu trc tng qut gm c 3 phn nh sau [Request-Line] [Headers] <CRLF> [Entity-Body] Request-Line: c c php nh sau: <Method><space><Request-URI><space><HTTP-Version><CRLF> Trong : - Method l tn phng thc HTTP, vi HTTP 1.0 ta c cc method chnh l: "GET", "HEAD" v "POST". - Request-URI l ng dn ti trang web cn ti, c th l ng dn tng i hay tuyt i. - HTTP-Version: cho bit phin bn HTTP ang s dng. V d: - Request line vi URI tuyt i: GET http://www.w3.org/pub/WWW/TheProject.html HTTP/1.0

- Request line vi URI tng i: GET /pub/WWW/TheProject.html HTTP/1.0 Headers: c 3 loi: General-Header; Request-Header; Entity-Header C nhiu Header khc nhau trong mi loi, y khng tin trnh by ht, nhng nhn chung, HTTP Header c c php nh sau: <field-name>: <field-value> <CRLF> Entity-Body: cha cc thng tin km theo request (v d khi ta nhn nt Submit trn 1 trang web s dng phng thc HTTP POST, trng thi ca cc nt check, gi tr trong cc edit text,... s c cha trong phn ny. V d: - Mt bn tin HTTP request dng phng thc GET: GET /path/file.html HTTP/1.0<CRLF> From: someuser@jmarshall.com<CRLF> User-Agent: HTTPTool/1.0<CRLF> <CRLF> Trong phng thc GET ny, phn body l trng (khng c message body) - Mt bn tin HTTP request dng phng thc POST: POST /path/script.cgi HTTP/1.0<CRLF> From: frog@jmarshall.com<CRLF> User-Agent: HTTPTool/1.0<CRLF> Content-Type: application/x-www-form-urlencoded<CRLF> Content-Length: 32<CRLF> <CRLF> home=Cosby&favorite+flavor=flies Dng 1 l request line Dng 2,3,4,5 l cc header Dng 6 ch cha 1 k t xung dng (<CRLF>) bo ht phn Header, bt u mesage body Dng 7 chnh l phn body y chng ta cn lu l di Headers khng c nh, nhng kt thc bng <CRLF>. Do khi vit chng trnh cho AVR, ta s tm ch no c 2 k t <CRLF> lin tip th l kt thc Headers. 1.1-Bn tin HTTP response:

a-Simple-Response: c cu trc rt n gin, ch cha phn Entity-Body [Entity-Body] b-Full-Response: c cu trc tng qut gm c 3 phn nh sau <Status-Line> <Headers> <CRLF> [Entity-Body] Status-Line: c c php nh sau <HTTP-Version><space><Status-Code><Space><Reason-Phrase><CRLF> Trong : - HTTP-Version: cho bit phin bn giao thc HTTP. V d: "HTTP/1.0" - Status-Code: cho bit m trng thi ca response. Gm 3 ch s, c qui nh nh sau + 1xx: Informational - cha c s dung, d phng + 2xx: Thnh cng (Success) - cho bit request c chp nhn v p u. + 3xx: Chuyn hng (Redirection) - yu cu client chuyn hng request + 4xx: Li do client (Client Error) - request khng hp l + 5xx: Li do sever (Server Error) - request hp l nhng server b li khng th tr li Cc Status-Code c th hay dng: + "200" ; OK + "201" ; Created + "202" ; Accepted + "204" ; No Content + "301" ; Moved Permanently + "302" ; Moved Temporarily + "304" ; Not Modified + "400" ; Bad Request + "401" ; Unauthorized + "403" ; Forbidden + "404" ; Not Found + "500" ; Internal Server Error + "501" ; Not Implemented + "502" ; Bad Gateway + "503" ; Service Unavailable - Reason-Phrase: cha ni dung text gii thch cho response. Headers: c php tng t header ca request, cng gm General-Header; Response-Header; Entity-

Header Entity-Body:cha phn ni dung tr li ca response (v du ni dung file html) V d: Mt response cho phng thc GET HTTP/1.0 200 OK<CRLF> Date: Fri, 31 Dec 1999 23:59:59 GMT<CRLF> Content-Type: text/html<CRLF> Content-Length: 1354<CRLF> <CRLF> <html> <body> <h1>Happy New Millennium!</h1> (more file contents) . . . </body> </html> Dng 1: Status-Line Dng 2: General Header Dng 3,4: Entity-Header Dng 5: <CRLF>, bo hiu kt thc headers Dng 6 tr i: Entity body

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

Bn no cha bit lm hoc li c th lm nh sau: 1-M notepad. 2-Copy code html sau vo: Code:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" dir="ltr" lang="en"> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>AVR web server</title> </head> <body style="background: #048C04; color: #FFFFFF"> <br> <table bgcolor="#489D48" border="0" width="975" cellpadding="0" cellspacing="0" align="center"> <tbody> <tr> <td height="31" align="center"> <div style="font-size:48pt; color:#F4FC8F"><strong>REMOTE CONTROL AVR WEBSERVER</strong></div> </td> </tr> </tbody> </table> <table width="100%" cellpadding="0" cellspacing="0">

<tbody> <tr> <td> <br> <div align="center"> <div style="background: #ffffff; color: #000000; width:975px; textalign: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/130842147558565 9804_574_0.jpg" width="320" height="240" /> </div> </td> <td style="padding: 5px 5px 5px 5px;" width="25%"> <div> <form method="POST" action=""> <p align="left"><input type="checkbox" name="RELAY1" value="ON"%RL1>Relay 01</p> <p align="left"><input type="checkbox" name="RELAY2" value="ON"%RL2>Relay 02</p> <p align="left"><input type="checkbox" name="RELAY3" value="ON"%RL3>Relay 03</p> <p align="left"><input type="checkbox" name="RELAY4" value="ON"%RL4>Relay 04</p> <p align="left"><input type="submit" value="Submit" name="CTRL"></p> </form> </div> </td> <td style="padding: 5px 5px 5px 5px;" width="50%"> <div> <table border="1" width="100%" id="table1"> <tr> <td>Environment Sensors</td> <td width="42">Value</td> <td width="33">Unit</td> <td width="150">&nbsp;</td> </tr> <tr> <td>Sensor 01</td> <td width="42">%AD0</td> <td width="33"><sup>o</sup>C</td> <td width="150">&nbsp;</td> </tr> <tr> <td>Sensor 02</td> <td width="42">%AD1</td> <td width="33"><sup>o</sup>C</td> <td width="150">&nbsp;</td> </tr> </table> </div> </td> </tr> </tbody> </table> </td> </tr> </tbody> </table>

<br><br><br> <div align="center">Timezone: GMT+7. Current time <span>%TI</span>.</div> <br> </div> </div> </div> <form action="footer" method="get"> <br> <div align="center"> <div align="center">Designed by thanh - tam</div> </div> </form> </td> </tr> </tbody> </table> </div> </body> </html>

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

User-Agent: Chrome/15.0<CRLF> <CRLF>

6-Webserver tr li bng mt bn tin HTTP response, vi phn Entity-body chnh l ni dung m HTML ca trang web trn: Code:
HTTP/1.0 200 Document follows<CRLF> Server: AVR_Small_Webserver<CRLF> Content-Type: text/html<CRLF> Content-Length: 1234<CRLF> <CRLF> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" dir="ltr" lang="en"> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>AVR web server</title> </head> <body style="background: #048C04; color: #FFFFFF"> <br> <table bgcolor="#489D48" border="0" width="975" cellpadding="0" cellspacing="0" align="center"> <tbody> <tr> <td height="31" align="center"> <div style="font-size:48pt; color:#F4FC8F"><strong>REMOTE CONTROL AVR WEBSERVER</strong></div> </td> </tr> </tbody> </table> <table width="100%" cellpadding="0" cellspacing="0"> <tbody> <tr> <td> <br> <div align="center"> <div style="background: #ffffff; color: #000000; width:975px; textalign: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/130842147558565 9804_574_0.jpg" width="320" height="240" /> </div> </td> <td style="padding: 5px 5px 5px 5px;" width="25%"> <div> <form method="POST" action=""> <p align="left"><input type="checkbox" name="RELAY1" value="ON"%RL1>Relay 01</p> <p align="left"><input type="checkbox" name="RELAY2" value="ON"%RL2>Relay 02</p> <p align="left"><input type="checkbox" name="RELAY3" value="ON"%RL3>Relay 03</p> <p align="left"><input type="checkbox" name="RELAY4" value="ON"%RL4>Relay 04</p> <p align="left"><input type="submit" value="Submit" name="CTRL"></p> </form> </div> </td>

<td style="padding: 5px 5px 5px 5px;" width="50%"> <div> <table border="1" width="100%" id="table1"> <tr> <td>Environment Sensors</td> <td width="42">Value</td> <td width="33">Unit</td> <td width="150">&nbsp;</td> </tr> <tr> <td>Sensor 01</td> <td width="42">%AD0</td> <td width="33"><sup>o</sup>C</td> <td width="150">&nbsp;</td> </tr> <tr> <td>Sensor 02</td> <td width="42">%AD1</td> <td width="33"><sup>o</sup>C</td> <td width="150">&nbsp;</td> </tr> </table> </div> </td> </tr> </tbody> </table> </td> </tr> </tbody> </table> <br><br><br> <div align="center">Timezone: GMT+7. Current time <span>%TI</span>.</div> <br> </div> </div> </div> <form action="footer" method="get"> <br> <div align="center"> <div align="center">Designed by thanh - tam</div> </div> </form> </td> </tr> </tbody> </table> </div> </body> </html>

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.jp g" 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.

By gi bt u phn Coding: Tng t, ta to ra cc file source v header trong project: File "http.c" Code:
//--------------------------------------------------------------------------// Writen by NTTam - PTITHCM //--------------------------------------------------------------------------#include "packet.h" #include "ethernet.h" #include "http.h" #include "webpage.h" #include "uart.h" #include "ntAVRnet.h"

File "http.h" Code:


//--------------------------------------------------------------------------// Writen by NTTam - PTITHCM //--------------------------------------------------------------------------#ifndef HTTP_H #define HTTP_H //--------------------------------------------------------------------------#endif //HTTP_H

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


//--------------------------------------------------------------------------// Writen by NTTam - PTITHCM //--------------------------------------------------------------------------#ifndef WEBPAGE_H #define WEBPAGE_H //---------------------------------------------------------------------------

#endif //WEBPAGE_H

By gi ta bt u vi file "webpage.h" trc, chuyn ni dung file HTML m ta son tho phn trc vo trong ROM ca AVR: Ta khai bo trong "webpage.h" mt chui k t lu trong b nh ROM: Code:
//--------------------------------------------------------------------------// Writen by NTTam - PTITHCM //--------------------------------------------------------------------------#ifndef WEBPAGE_H #define WEBPAGE_H // #include <avr/pgmspace.h> PROGMEM char Page1[] = {}; //--------------------------------------------------------------------------#endif //WEBPAGE_H

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

<tr> <td> <br> <div align=\"center\"> <div style=\"background: #ffffff; color: #000000; width:975px; textalign: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/13084214755856 59804_574_0.jpg\" width=\"320\" height=\"240\" /> </div> </td> <td style=\"padding: 5px 5px 5px 5px;\" width=\"25%\"> <div> <form method=\"POST\" action=\"\"> <p align=\"left\"><input type=\"checkbox\" name=\"RELAY1\" value=\"ON\"%RL1>Relay 01</p> <p align=\"left\"><input type=\"checkbox\" name=\"RELAY2\" value=\"ON\"%RL2>Relay 02</p> <p align=\"left\"><input type=\"checkbox\" name=\"RELAY3\" value=\"ON\"%RL3>Relay 03</p> <p align=\"left\"><input type=\"checkbox\" name=\"RELAY4\" value=\"ON\"%RL4>Relay 04</p> <p align=\"left\"><input type=\"submit\" value=\"Submit\" name=\"CTRL\"></p> </form> </div> </td> <td style=\"padding: 5px 5px 5px 5px;\" width=\"50%\"> <div> <table border=\"1\" width=\"100%\" id=\"table1\"> <tr> <td>Environment Sensors</td> <td width=\"42\">Value</td> <td width=\"33\">Unit</td> <td width=\"150\">&nbsp;</td> </tr> <tr> <td>Sensor 01</td> <td width=\"42\">%AD0</td> <td width=\"33\"><sup>o</sup>C</td> <td width=\"150\">&nbsp;</td> </tr> <tr> <td>Sensor 02</td> <td width=\"42\">%AD1</td> <td width=\"33\"><sup>o</sup>C</td> <td width=\"150\">&nbsp;</td> </tr> </table> </div> </td> </tr> </tbody> </table> </td> </tr> </tbody> </table> <br><br><br>

<div align=\"center\">Timezone: GMT+7. Current time <span>%TI</span>.</div> <br> </div> </div> </div> <form action=\"footer\" method=\"get\"> <br> <div align=\"center\"> <div align=\"center\">Designed by thanh - tam</div> </div> </form> </td> </tr> </tbody> </table> </div> </body> </html>

3-Ta thm du nhy kp vo u v cui mi dng. 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/xhtml1transitional.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; textalign: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/13084214755856 59804_574_0.jpg\" width=\"320\" height=\"240\" />" "</div>" "</td>" "<td style=\"padding: 5px 5px 5px 5px;\" width=\"25%\">" "<div>" "<form method=\"POST\" action=\"\">" "<p align=\"left\"><input type=\"checkbox\" name=\"RELAY1\" value=\"ON\"%RL1>Relay 01</p>" "<p align=\"left\"><input type=\"checkbox\" name=\"RELAY2\" value=\"ON\"%RL2>Relay 02</p>" "<p align=\"left\"><input type=\"checkbox\" name=\"RELAY3\" value=\"ON\"%RL3>Relay 03</p>" "<p align=\"left\"><input type=\"checkbox\" name=\"RELAY4\" value=\"ON\"%RL4>Relay 04</p>" "<p align=\"left\"><input type=\"submit\" value=\"Submit\" name=\"CTRL\"></p>" "</form>" "</div>" "</td>" "<td style=\"padding: 5px 5px 5px 5px;\" width=\"50%\">" "<div>" "<table border=\"1\" width=\"100%\" id=\"table1\">" "<tr>" "<td>Environment Sensors</td>" "<td width=\"42\">Value</td>" "<td width=\"33\">Unit</td>" "<td width=\"150\">&nbsp;</td>" "</tr>" "<tr>" "<td>Sensor 01</td>" "<td width=\"42\">%AD0</td>" "<td width=\"33\"><sup>o</sup>C</td>" "<td width=\"150\">&nbsp;</td>" "</tr>" "<tr>" "<td>Sensor 02</td>" "<td width=\"42\">%AD1</td>" "<td width=\"33\"><sup>o</sup>C</td>" "<td width=\"150\">&nbsp;</td>" "</tr>" "</table>" "</div>" "</td>" "</tr>" "</tbody>" "</table>" "</td>" "</tr>"

"</tbody>" "</table>" "<br><br><br>" "<div align=\"center\">Timezone: GMT+7. Current time <span>%TI</span>.</div>" "<br>" "</div>" "</div>" "</div>" "<form action=\"footer\" method=\"get\">" "<br>" "<div align=\"center\">" "<div align=\"center\">Designed by thanh - tam</div>" "</div>" "</form>" "</td>" "</tr>" "</tbody>" "</table>" "</div>" "</body>" "</html>"}; //--------------------------------------------------------------------------#endif //WEBPAGE_H

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

Tip theo, ta quay li file "http.h". Thm cc define cho cc method ca request: Code:
// #define #define #define #define // #define #define #define // HTTP_REQUEST_GET HTTP_REQUEST_POST HTTP_REQUEST_HEAD HTTP_REQUEST_UNKNOWN HTTP_REQUEST_GET_STR HTTP_REQUEST_POST_STR HTTP_REQUEST_HEAD_STR 1//"GET" 2//"POST" 3//"HEAD" 4//Request quai qui gi do ma ta khong biet "GET" "POST" "HEAD"

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


// struct httpRequest{ unsigned char method; unsigned char *requestURI; unsigned char *version; unsigned char *header; unsigned char *body; unsigned int bodyLen; }; //end with space //end with space //end with \n\r //end with \n\r\n\r //

y cc bn lu l khc vi cc header khc, ta dng ch yu bin con tr tr cc field trong bn tin request, v kch thc cc field trong bn tin khng c nh, nn v tr bt u field cng khng c nh. Ta dng bin co tr tr n u mi field, cn kt thc field th ng

nhin l trc khi bt u filed tip theo, tr field cui cng l body, ta cho n 1 bin chiu di. Webserver phi c kh nng thit lp ng thi nhiu phin kt ni, do ta khai bo 1 struct na lu thng tin v mi phin kt ni HTTP: Code:
struct httpSession{ unsigned char status; //Trang thai hien tai const prog_char *headerPointer; //Con tro den header trong bo nho chuong trinh const prog_char *bodyPointer; //Con tro den du lieu can gui trong bo nho chuong trinh unsigned char *authStr; //Con tro den chuoi xac thuc unsigned char auth; //Xac thuc struct httpRequest rqst; //Request tuong ung struct tcpSession *pTCPSession; };

Trong struct trn ta c dng t kha prog_char ( ch b nh chng trnh: ROM) nn cc bn nh include file "pgmspace.h" vo (u file) nu khng s c bo li: Code:
#include <avr/pgmspace.h>

Cui cng l define cc trng thi ca 1 phin HTTP v s phin ti a c th thit lp ng thi: Code:
// #define #define #define #define #define // #define // HTTP_STATUS_IDLE HTTP_STATUS_GOT_REQUEST HTTP_STATUS_HEADER_SENT HTTP_STATUS_HEADER_RECEIVED HTTP_STATUS_FINISH MAX_HTTP_SESSION 0 1 2 3 4 8

Ti lt file source "http.c" u tin ta khai bo mt s bn tin response chun webserver s dng: Bn tin response cho mt request GET/POST hp l, km theo s l ni dung trang web: Code:
prog_char http_pageheader_ok[]={ AVR_Small_Webserver\r\n" "Content-Type: text/html\r\n\r\n"}; "HTTP/1.0 200 Document follows\r\n" "Server:

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" "WWWAuthenticate: Basic realm=\"NeedPassword\"" "\r\nContentType: text/html\r\n\r\n"}; "HTTP/1.0 401 Unauthorized\r\n" "Server:

Bn tin bo vic xc thc tht bi: Code:


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

Bn tin bo li request mt i tng khng c: Code:


prog_char http_error_notimp[]={ AVR_Small_Webserver\r\n" "WWWAuthenticate: Basic realm=\"My AVR web server\"" "\r\nContentType: text/html\r\n\r\n"}; "HTTP/1.1 501 Not Implemented\r\n" "Server:

Khai bo 1 array cc bin struct cha thng tin v cc phin HTTP: Code:
struct httpSession httpSessionTable[MAX_HTTP_SESSION];

Khai bo 1 char array cha chui xc thc: Code:


unsigned char http_auth_password[20];

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


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

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

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

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

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

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

} rqst->body = &buffer[i]; rqst->bodyLen = bufferLen - i; #ifdef HTTP_DEBUG printf("Buffer Len:%d\r\n",bufferLen); printf("URI start:%d\r\n",(rqst->requestURI - buffer)); printf("HTTP Version:%d\r\n",(rqst->version - buffer)); printf("Header:%d\n\r",(rqst->header - buffer)); printf("Body:%d\n\r",(unsigned int)(rqst->body - buffer)); printf("Body:%x-%x\n\r",(unsigned int)(rqst->body),(unsigned int)buffer); printf("Body i:%d\n\r",i); #endif }

V hm ly gi tr ca 1 trng HTTP Header: Code:


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

Last edited by nttam79; 23-11-11 at 11:20.

Chia s
o o o o o

| Cm n

tienhuypro, robocon2011 v hieppro89 cm n ni dung ny. Tr li Reply With Quote 23-11-11 11:57 #163 nttam79

Thnh vin chnh thc Tham gia Feb 2009 Bi vit 91 Tip theo, ta vit 2 hm chnh ca giao thc HTTP: hm gi mt bn tin HTTP i v hm x l 1 request nhn c: u tin, ta cn 2 hm tm kim chui m ta s s dng trong 2 hm chnh trn: - Hm tm 1 chui lu trong b nh chng trnh (ROM) trong 1 chui lu trong RAM Code:
//--------------------------------------------------------------------------unsigned int findstr(const prog_char progstr[],unsigned char* str,unsigned int len) { unsigned int i,j; i=0; j=0; while(i<len){ if(str[i++] != pgm_read_byte(progstr + j++)){ j = 0; } if(pgm_read_byte(progstr + j) == 0){ return(i-j); } } return(-1); }

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


//--------------------------------------------------------------------------unsigned int findstrdatamem(unsigned char* str1,unsigned char* str2,unsigned int len) { unsigned int i,j; i=0; j=0; while(i<len){ if(str2[i++] != str1[j++]){ j = 0;

} if(str1[j] == 0){ return(i-j); } if(str2[i] == 0){ return(-1); } } return(-1); }

V y l hm gi i mt bn tin HTTP: Code:


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

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

Hm x l 1 request nhn c: Code:


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

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

HTTPSend(http_pageheader_ok,sizeof(http_pageheader_ok)-1,pSession,0); HTTPSend(Page1,sizeof(Page1)-1,pSession,1); httpSessionTable[i].status = HTTP_STATUS_IDLE; return; }else if(findstr(PSTR("APPLY=Apply"),buffer,bufferLen) != -1){ HTTPSend(http_pageheader_ok,sizeof(http_pageheader_ok)-1,pSession,0); HTTPSend(Page1,sizeof(Page1)-1,pSession,1); httpSessionTable[i].status = HTTP_STATUS_IDLE; }else{ HTTPSend("",0,pSession,0); } } } }

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

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

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


TCPInit(); httpInit();

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

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

Thy cho em hi cu ny vi: Hm ny trong file udp.c: void udpSend(unsigned long dstIp, unsigned int dstPort, unsigned int len, unsigned char* udpData) Cn cu lnh gi hm ny trong file dhcp.c:udpSend(DhcpServerIP, DHCP_UDP_SERVER_PORT, DHCP_UDP_CLIENT_PORT, DHCP_HEADER_LEN+3+6+6+1, (unsigned char*)packet); agrument (s bin gi hm khng nh nhau)ca cu lnh gi hm ko ng, e ko bit sa th no? Mong thy gip!

ci ny, thy Tm ni r l sa li ri m. bn tm k li xem, c th nh sau: void udpSend(unsigned long dstIp, unsigned int dstPort, unsigned int srcPort, unsigned int len, unsigned char* udpData) { struct ntUDPHeader* udpHeader; udpHeader = (struct ntUDPHeader*)(udpData - UDP_HEADER_LEN); len += UDP_HEADER_LEN; udpHeader->desPort = HTONS(dstPort); udpHeader->srcPort = HTONS(srcPort); udpHeader->Len = HTONS(len); udpHeader->Checksum = 0; ipSend(dstIp, IP_PROTO_UDP, len, (unsigned char*)udpHeader); }

Thy i, alij gp vn m debug ko ra. Thy coi hnh em vi. on code ny cng ko bit copy vo u cho ng. 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();//// }

Chia s
o o o o

| Cm n

Tr li Reply With Quote

24-11-11 00:22 #172 nttam79

Thnh vin chnh thc Tham gia Feb 2009 Bi vit 91 Nguyn vn bi dinh_dong Thy i, alij gp vn m debug ko ra. Thy coi hnh em vi. on code ny cng ko bit copy vo u cho ng. File nh Km 35926 on code nm trong file "timer.c" Nh include cc file: Code:
#include <avr/io.h> #include <avr/interrupt.h>

Kim tra li c th bn copy trng u .

Chia s
o o o o o

| Cm n

dinh_dong cm n ni dung ny. Tr li Reply With Quote 24-11-11 00:25 #173 hieppro89

Thnh vin chnh thc Tham gia Mar 2010 Bi vit 35

Nhm x hi

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();//// } ci ny n gin thui m sa trong file Timer.c bn k code TIMER_INTERRUPT_HANDLER(SIG_OVERFLOW1) c v TIMER_INTERRUPT_HANDLER(SIG_OVERFLOW1) mi khi Thy bo sa li cp nht thi gian cho TCP v DHCP c g khc nhau ko? th bc ch cn Copy ci TIMER_INTERRUPT_HANDLER(SIG_OVERFLOW1) mi ln ci c l ok ngay m y l file timer.c ca em: //---------------------------------------------------------------------------// Writen by NTTam - PTITHCM //---------------------------------------------------------------------------#include <avr/io.h> #include <avr/interrupt.h> #include "ntAVRnet.h" #include "timer.h" #include "ethernet.h" #include "arp.h"

#include "dhcp.h" #include "tcp.h" //#include "tcp.h" //---------------------------------------------------------------------------extern volatile unsigned int time_watchdog; static volatile unsigned long UptimeMs; static volatile unsigned char Counter10ms; static volatile unsigned int Counter1s; //---------------------------------------------------------------------------void timer1Init(void) { // initialize timer 1 // set prescaler on timer 1 TCCR1B = (TCCR1B & ~TIMER_PRESCALE_MASK) | TIMER1PRESCALE; // set prescaler TCNT1H = 0; // reset TCNT1 TCNT1L = 0; TIMSK |= (1<<TOIE1); // enable TCNT1 overflow TCNT1 = 0xFFFF - TIMER1_INTERVAL; } void timerInit(void) { timer1Init(); sei(); } //! Interrupt handler for tcnt1 overflow interrupt //thm vo cc hm ca^.p nha^.t tho+`i gian cu?a giao thu+'c TCP v DHCP 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();//// } cn y l file trc khi sa i: //---------------------------------------------------------------------------void timer1Init(void) { // initialize timer 1 // set prescaler on timer 1

TCCR1B = (TCCR1B & ~TIMER_PRESCALE_MASK) | TIMER1PRESCALE; // set prescaler TCNT1H = 0; // reset TCNT1 TCNT1L = 0; TIMSK |= (1<<TOIE1); // enable TCNT1 overflow TCNT1 = 0xFFFF - TIMER1_INTERVAL; } void timerInit(void) { timer1Init(); sei(); } //! Interrupt handler for tcnt1 overflow interrupt TIMER_INTERRUPT_HANDLER(SIG_OVERFLOW1) { //Tai nap gia tri timer 1 TCNT1 = 0xFFFF - TIMER1_INTERVAL; //Cap nhat watchdog timer if((time_watchdog++) > 120){ time_watchdog = 0; ethInit(); } Counter1s++; arpTimer(); //TCPCheckTimeOut(); } bc xem li trang 6 v trang 13 tin so snh nh best regards!

Truy cp vo web:

Chp mn hnh desktop:

Vy l code n nh, xo nu th no l do cc bn thi. Thy b cn nh mnh d thng hng .

Mi i do v thy anh Tm gi code mng wa nn th lin. Ok anh ah, em xem khc th no ri ni sau. Nhng sao code ny khng cn ng nhp lun Cn phn LCD, ADC nhit hm no xong em port ln lun. File nh Km 36148 , bit ti sao ri: trong chng trnh chnh (main()) mnh qun gi hm httpInit khi ng chui m ha username/password. Mi ngi thm vo nh.

You might also like