;;======================================================================== ;; ;; Program: TCP/IP stack and HTTP-server in a chip ;; Idea: Shrikumar H. <shri@cs.umass.edu> ;; Author: Denis Petrov <zhengxi@operamail.com> ;; Platform: Microchip PIC16F84 ;; Date: 17.09.99 ;; LastDate: 25.09.99 ;; ;;======================================================================== ;; todo: watching tcp_online ;; use WDT ;; more than 1 socket include masmpic.inc .386 ;;======================================================================== ;; General settings ;;======================================================================== QUARTZ_FREQ = 6000000 RS_BAUD = 19200 RS_DATA = 8 RS_TICKS = (QUARTZ_FREQ/4)/RS_BAUD ; [non-volatile] ADDR_MYSELF_0 = 219 ; 219.192.55.208 ( ~my phone# :) ADDR_MYSELF_1 = 192 ADDR_MYSELF_2 = 55 ADDR_MYSELF_3 = 208 TCP_PORT_HTTP = 80 ; 1..255 TCP_RCV_WINDOW = 128;!sic!; [non-volatile] TCP_SND_WINDOW = 128 ; [non-volatile] RS_MONITOR = 1 ; monitor works over raw RS232 FS_UNIT_SIZE = 128 ; [non-volatile] FS_ROOT_DIR_ENTRIES = 8 ; min 2: INDEX and ERROR. FS_USE_INTERNAL_ROM = 1 FS_INTERNAL_ROM_UNITS = 4 ; number of 128-byte pages FS_USE_INTERNAL_EEPROM = 0 ; FS_USE_EXTERNAL_ROM = 0 ;;======================================================================== ;; DATA RAM mapping ;;======================================================================== TCPR_RPORT_H = SRAM0 ; remote TCP port TCPR_RPORT_L = SRAM1 TCPR_LPORT_H = SRAM2 ; local TCP port, TCPR_LPORT_H==0 TCPR_LPORT_L = SRAM3 TCPR_SEQ_L3 = SRAM4 TCPR_SEQ_L2 = SRAM5 TCPR_SEQ_L1 = SRAM6 TCPR_SEQ_L0 = SRAM7 TCPR_ACK_L3 = SRAM8 TCPR_ACK_L2 = SRAM9 TCPR_ACK_L1 = SRAM10 TCPR_ACK_L0 = SRAM11 TCPR_HLEN = SRAM12 ; Is not used when sending не используется при посылке TCPR_FLAG = SRAM13 ; ÎÅ ÉÓÐÏÌØÚÕÅÔÓÑ ÐÒÉ ÐÏÓÙÌËÅ TEMP_0 = SRAM2 TEMP_1 = SRAM12 TEMP_2 = SRAM13 HTTP_UNITIDX = SRAM14 ;*** HTTP_FILESIZE_H = SRAM15 ;*** HTTP_FILESIZE_L = SRAM16 ;*** HTTP_NAME_0 = SRAM14 HTTP_NAME_1 = SRAM15 HTTP_NAME_2 = SRAM16 if RS_MONITOR MON_ADDR_H = SRAM14 MON_ADDR_L = SRAM15 MON_TAG = SRAM16 ; like (as) 'R', 'W', 'A' ×ÒÏÄÅ 'R','W','A' endif ; socket data, it's valid if tcp_online==1 TCPR_POS = SRAM17 ; iterator 0 -->] 80..FF ; bytes received from the time communication opened ; ÐÒÉÎÑÔÏ ÂÁÊÔ Ó ÏÔËÒÙÔÉÑ ÓÏÅÄÉÎÅÎÉÑ TCPS_ACK = SRAM18 TCPS_SEQ = SRAM19 TCPS_LEN = SRAM20 ; for retransmit TCPS_FLAG = SRAM21 ; for retransmit RX_BYTE = SRAM22 ; [soft uart] TX_BYTE = RX_BYTE ; [soft uart] IP_POS = SRAM23 ; iterator IP_HLEN = SRAM24 ; IP header len (incoming only) IP_LEN = SRAM25 ; IP packet len IP_SUM_0 = SRAM26 ; TCP/IP chksum IP_SUM_1 = SRAM27 ; --//-----//-- low octet IP_ADR_0 = SRAM28 ; remote IP address IP_ADR_1 = SRAM29 ; --//-- IP_ADR_2 = SRAM30 ; --//-- IP_ADR_3 = SRAM31 ; --//-- DefBit B_HTTP_STATE_0, TCPS_FLAG, 5 DefBit B_HTTP_STATE_1, TCPS_FLAG, 6 DefBit B_TCP_ONLINE, TCPS_FLAG, 7 ;DefBit B_LED_1, PORTA, 3 ;DefBit B_LED_2, PORTA, 2 DefBit B_RS232_RxD, PORTB, 0 DefBit B_RS232_TxD, PORTA, 3 DefBit B_RS232_CTS, PORTA, 2 DefBit B_SLIP_OUTPKT, IP_HLEN, 7 DefBit B_SLIP_ESCAPE, IP_HLEN, 6 ;;======================================================================== ;; Useful macros ;;======================================================================== TXLW macro k movlw (k) call _tx endm SLITXLW macro k movlw (k) call _slitx endm SUM0 MACRO x:req __TMPSUM=(((x)+((x) shr 16)) shr 8) movlw __TMPSUM ENDM SUM1 MACRO x:req __TMPSUM=(((x)+((x) shr 16)) shr 0) movlw __TMPSUM ENDM ;;======================================================================== ;; Code ;;======================================================================== _start: clrf INTCON ; Disable Interrupts ÚÁÐÒÅÔÉÔØ ×ÓÅ ÐÒÅÒÙ×ÁÎÉÑ ? movlw 01001111b ; "_-", WDT/128 option jump _init _interrupt: ; ; Soft UART ( simplex :( ) ; ; S01234567T ; ; 115.2 ; ; 57.6 ; ; 38.4 ; ; 19.2 ; _________ ; ; _^_"þ" ; _interrupt_b0: ; 5 ; Interrupt ÏÂÒÁÂÏÔÞÉÔ ÐÒÅÒÙ×ÁÎÉÑ INT call _delay4 ; 4 ; Delay 4 (ÍÏÍÅÎÔ "þ") movlw 8 ; 1 ; 8Nx _rx_next: bcf B_RS232_CTS ; 1 ; fall CTS call _delay_x_9 ; x-9 ; bcf C ; 1 ; skip1 B_RS232_RxD ; 1 ; bsf C ; 1 ; C:=RS232_RxD rrf RX_BYTE,F ; 1 ; addlw -1 ; 1 ; jnz _rx_next ; 3 ; movf RX_BYTE,w ; xorlw 0C0h ; jnz _no_C0 ; Starting to recieve ÎÁÞÉÎÁÅÍ ÐÒÉÅÍ bcf B_SLIP_OUTPKT ; New package (SLIP END) ÎÏ×ÏÇÏ ÐÁËÅÔÁ (SLIP END) clrf IP_POS ; clrf IP_SUM_0 ; clrf IP_SUM_1 ; jump _rx ; _no_C0: j0 B_SLIP_OUTPKT,_mode_slip; if the symbol being revieved is not in the package ; ÅÓÌÉ ÐÒÉÎÉÍÁÅÍÙÊ ÓÉÍ×ÏÌ ×ÎÅ ÐÁËÅÔÁ _mode_terminal: xorlw <00Dh xor 0C0h> ; jnz _rx ; Modem emulation ÜÍÕÌÑÃÉÑ ÍÏÄÅÍÁ: TXLW 'O' ; Respond to AT command ÏÔ×ÅÔ ÎÁ AT-ËÏÍÁÎÄÙ TXLW 'K' ; TXLW 0Dh ; jump _rx ; _mode_slip: j0 B_SLIP_ESCAPE,_no_slip_escape xorlw <0DCh xor 0C0h> ; Treatment of the 2nd byte ; ÏÔÒÁÂÏÔËÁ ×ÔÏÒÏÇÏ ÂÁÊÔÁ movlw 0DBh ; Special order SLIP ÓÐÅÃ.ÐÏÓÌÅÄÏ×ÁÔÅÌØÎÏÓÔÅÊ SLIP: skipnz ; 0xDB,0xDC --> 0xC0 movlw 0C0h ; 0xDB,0xDD --> 0xDB movwf RX_BYTE ; RX_BYTE=(RX_BYTE==0xDC?0xC0:0xDB) ; jump _end_slip_escape ; _no_slip_escape: ; bsf B_SLIP_ESCAPE ; if OxDB is recieved, then ÅÓÌÉ ÐÒÉÎÑÔ 0xDB, ÚÎÁÞÉÔ xorlw <0DBh xor 0C0h> ; this is the first byte ÜÔÏ ÐÅÒ×ÙÊ ÂÁÊÔ jz _rx ; special order SLIP ÓÐÅÃ.ÐÏÓÌÅÄÏ×ÁÔÅÌØÎÏÓÔÉ SLIP: _end_slip_escape: bcf B_SLIP_ESCAPE ; movf RX_BYTE,W call _checksum_byte ; control sum refreshement (renewal?) ; ÏÂÎÏ×ÌÅÎÉÅ ËÏÎÔÒÏÌØÎÏÊ ÓÕÍÍÙ ; of the package being recieved ; ÐÒÉÎÉÍÁÅÍÏÇÏ ÐÁËÅÔÁ movf IP_POS,W ; treatment of the first 0x13 bytes ; ÏÂÒÁÂÏÔËÁ ÐÅÒ×ÙÈ 0x13 ÂÁÊÔ addlw -20 ; after SLIP END as a header ; ÐÏÓÌÅ SLIP.END ËÁË ÚÁÇÏÌÏ×ÏË jc _xxxx ; of the IP package IP ÐÁËÅÔÁ rlf IP_POS,W ; clrf PCLATH ; usefull but not required ; ÜÔÏ ÐÏÌÅÚÎÏ, ÎÏ ÎÅ ÎÅÏÂÈÏÄÉÍÏ addwf PCL,F ; movf RX_BYTE,W ; IPhdr+ 0 Version & IHL movwf IP_HLEN ; rlf IP_HLEN,F ; IPhdr+ 1 Type of Service jump _01_ ; movlw 0 ; IPhdr+ 2 Total Length (hi) jump _rx_byte_must_equal_w ; movf RX_BYTE,W ; IPhdr+ 3 Total Length (lo) movwf IP_LEN ; jump _finish ; IPhdr+ 4 Identification (hi) _01_: bcf IP_HLEN,7 ; jump _finish ; IPhdr+ 5 Identification (lo) nop ; jump _finish ; IPhdr+ 6 Flags & Fragment Offset (hi) nop ; movlw 0 ; IPhdr+ 7 Fragment Offset (lo) jump _rx_byte_must_equal_w ; jump _finish ; IPhdr+ 8 Time to Live nop ; movlw 6 ; IPhdr+ 9 Protocol jump _rx_byte_must_equal_w ; jump _finish ; IPhdr+10 Header Checksum (hi) nop ; jump _finish ; IPhdr+11 Header Checksum (lo) nop ; movlw IP_ADR_0 ; IPhdr+12 Source Address jump _save_rx_byte ; movlw IP_ADR_1 ; IPhdr+13 jump _save_rx_byte ; movlw IP_ADR_2 ; IPhdr+14 jump _save_rx_byte ; movlw IP_ADR_3 ; IPhdr+15 jump _save_rx_byte ; movlw ADDR_MYSELF_0 ; IPhdr+16 Destination Address jump _rx_byte_must_equal_w ; movlw ADDR_MYSELF_1 ; IPhdr+17 jump _rx_byte_must_equal_w ; movlw ADDR_MYSELF_2 ; IPhdr+18 jump _rx_byte_must_equal_w ; movlw ADDR_MYSELF_3 ; IPhdr+19 _rx_byte_must_equal_w: xorwf RX_BYTE,W ; jnz _error ; _xxxx: movf IP_HLEN,W ; IP_POS-IP_HLEN - on which position ÎÁ ËÁËÏÍ ÍÅÓÔÅ subwf IP_POS,W ; after the IP header, the recieved byte can be found ; ÐÒÉÎÑÔÙÊ ÂÁÊÔ ÎÁÈÏÄÉÔÓÑ ÐÏÓÌÅ IP ÚÁÇÏÌÏ×ËÁ jc _post_ip ; ... or is this still an IP header? ; ... ÉÌÉ ÜÔÏ ×ÓÅ ÅÝÅ IP ÚÁÇÏÌÏ×ÏË? _no_post_ip: xorlw 0FFh ; and if this is the last byte of the IP header ; Á ÅÓÌÉ ÜÔÏ ÐÏÓÌÅÄÎÉÊ ÂÁÊÔ IP ÚÁÇÏÌÏ×ËÁ jnz _finish ; IP_SUM should be 0 IP_SUM ÄÏÌÖÎÁ ÂÙÔØ ÒÁ×ÎÁ 0 movf IP_SUM_0,W ; iorwf IP_SUM_1,W ; jnz _error ; wrong sum for monitoring ; ÎÅÐÒÁ×ÉÌØÎÁÑ ËÏÎÔÒÏÌØÎÁÑ ÓÕÍÍÁ... _finish: incf IP_POS,F ; Next! ÓÌÅÄÕÀÝÉÊ! jump _rx ; _post_ip: addlw -14 ; saving the first 14 bytes of the TCP header ; ÓÏÈÒÁÎÑÅÍ ÐÅÒ×ÙÅ 14 ÂÁÊÔ TCP ÚÁÇÏÌÏ×ËÁ jnc _save_as_tcp_header ; jnz _no_correct_tcp_hlen ; rrf TCPR_HLEN,F ; if(IP_POS-IP_HLEN==14) rrf TCPR_HLEN,F ; { bcf TCPR_HLEN,7 ; TCPR_HLEN=(TCPR_HLEN<<2)&0x3F; bcf TCPR_HLEN,6 ; } _no_correct_tcp_hlen: subwf TCPR_HLEN,W ; saving bytes 5, 6 and 7 of the TCP _connection_ ; ÓÏÈÒÁÎÑÅÍ 5,6É7 ÂÁÊÔÙ TCP _ÓÏÅÄÉÎÅÎÉÑ_. addlw -15 ; if now (W<14) - than the name of the file ; ÅÓÌÉ ÓÅÊÞÁÓ (W<14) - ÚÎÁÞÉÔ ÉÍÑ ÆÁÊÌÁ jc _no_save_rx_byte ; came in multiple packages, for example, ; ÐÒÉÛÌÏ × ÎÅÓËÏÌØËÉÈ ÐÁËÅÔÁÈ, ÎÁÐÒÉÍÅÒ, ; GET /xxx was typed in the telnet-client ; GET /xxx ÂÙÌÏ ÎÁÂÒÁÎÏ × telnet-ËÌÉÅÎÔÅ ; so this check is not necessary ; ÔÁË ÞÔÏ ÜÔÁ ÐÒÏ×ÅÒËÁ ÎÅ Ñ×Ì. ÎÅÏÂÈÏÄÉÍÏÊ, ; if only www-browser will be used ; ÅÓÌÉ ÂÕÄÅÔ ÐÏÌØÚÏ×ÁÔØÓÑ ÔÏÌØËÏ www-browser. subwf TCPR_POS,W ; like first symbols of the file name in "GET /" ; ËÁË ÐÅÒ×ÙÅ ÓÉÍ×ÏÌÙ ÉÍÅÎÉ ÆÁÊÌÁ × "GET /.." addlw (-1-(5+3)) ; W=TCPR_POS-(TCPR_HLEN-(IP_POS-IP_HLEN-14)) addlw 3 ; (5.7)->(FD.FF) (5.7)->(0.2) jnc _no_save_rx_byte if (HTTP_NAME_0-(TCPR_RPORT_H+14)) ne 0 addlw (HTTP_NAME_0-(TCPR_RPORT_H+14)) endif _save_as_tcp_header: addlw TCPR_RPORT_H+14 _save_rx_byte: movwf FSR ; [W]:=RX_BYTE - is often used ÞÁÓÔÏ ÉÓÐÏÌØÚÕÅÔÓÑ movf RX_BYTE,W ; movwf INDR ; _no_save_rx_byte: incf IP_POS,W ; ÅÓÌÉ ÐÒÉÎÑÔ ÐÏÓÌÅÄÎÉÊ ÂÁÊÔ subwf IP_LEN,W ; if the last byte of the IP package is recieved... ; IP ÐÁËÅÔÁ... jnz _finish ; movf IP_HLEN,W ; IP_LEN-=IP_HLEN; subwf IP_LEN,F ; call _chksum_pseudoheader ; control check sum of the TCP package's header/body ; ÐÒÏ×ÅÒËÁ ËÏÎÔÒÏÌØÎÏÊ ÓÕÍÍÙ TCP ÚÁÇÏÌÏ×ËÁ/ÔÅÌÁ ÐÁËÅÔÁ movf IP_SUM_0,W ; iorwf IP_SUM_1,W ; skipnz ; call _process_tcp ; jump _error ; ;=========================================================================== ; TX routines ;=========================================================================== ;_txhex: movwf FSR ; swapf FSR,W ; call _txhex0 ; movf FSR,W ;_txhex0:andlw 00001111b ; addlw -10 ; skipnc ; addlw 7 ; addlw 58 ; jump _tx ;;------------------------------------------------ _slitx_csum: movf IP_SUM_0,W ; pass (or deliver) the control sum ; ÐÅÒÅÄÁÔØ ËÏÎÔÒÏÌØÎÕÀ ÓÕÍÍÕ call _slitx ; (2 bytes) (Ä×Á ÂÁÊÔÁ) movf IP_SUM_1,W ; jump _slitx ;;------------------------------------------------ _slitx4: movwf FSR ; pass (or deliver) 4 bytes (W[0]...W[3]) ; ÐÅÒÅÄÁÔØ 4 ÂÁÊÔÁ (W[0]..W[3]) call _slitx2 ; with the control sum correction ; Ó ËÏÒÒÅËÃÉÅÊ ËÏÎÔÒÏÌØÎÏÊ ÓÕÍÍÙ _slitx2: movf INDR,W ; pass (or deliver) 2 bytes (FSR[0]...FSR[1]) ; ÐÅÒÅÄÁÔØ 2 ÂÁÊÔÁ (FSR[0]..FSR[1]) call _checksum_hi call _slitx1 movf INDR,W call _checksum_lo _slitx1: movf INDR,W ; pass (or deliver) 1 byte (*FSR++) ; ÐÅÒÅÄÁÔØ 1 ÂÁÊÔ (*FSR++) incf FSR,F ; jump _slitx ;;------------------------------------------------ _tx_0_0: call _tx_0 ; pass (or deliver) 2 zeros ; ÐÅÒÅÄÁÔØ Ä×Á ÎÕÌÑ _tx_0: movlw 000h ; pass (or deliver) a zero ; ÐÅÒÅÄÁÔØ ÎÕÌØ _slitx: xorlw 0C0h ; pass (deliver) a byte by (using) SLIP protocol ; ÐÅÒÅÄÁÔØ ÂÁÊÔ ÐÏ ÐÒÏÔÏËÏÌÕ SLIP jnz _ne_C0 ; i.e. ( = that is) with substitutions ; Ô.Å. Ó ÚÁÍÅÎÁÍÉ TXLW 0DBh ; 0xC0 --> 0xDB,0xDC movlw 0DCh ; 0xDB --> 0xDB,0xDD jump _tx ; _ne_C0: xorlw <0DBh xor 0C0h> ; jnz _tx11 ; call _tx11 ; movlw <0DDh xor 0DBh> ; _tx11: ; xorlw 0DBh ; _tx: bsf B_RS232_TxD ; just pass (deliver) one byte ; ÐÒÏÓÔÏ ÐÅÒÅÄÁÔØ ÏÄÉÎ ÂÁÊÔ movwf TX_BYTE ; IN: W movlw <(-(RS_DATA+1))shl 4> ; OUT: TX_BYTE:=W _tx_loop_c: bsf C ; 1 _tx_loop: call _delay_x_9 rrf TX_BYTE,F ; 1 ; 1 jnc _c_is_clear ; 2 ; 3 addlw 10h ; 1 bcf B_RS232_TxD ; 1 jnz _tx_loop_c ; 3 _delay_x_9: ; upon technical-delay it is not allowed: ; ÐÒÉ TX-ÚÁÄÅÒÖËÅ ÎÅÌØÚÑ: ; 1. to change flag STATUS.C ; 1. ÉÚÍÅÎÑÔØ ÆÌÁÇ STATUS.C ; 2. to overload the stream of returns ; 2. ÓÉÌØÎÏ ÐÅÒÅÇÒÕÖÁÔØ ÓÔÅË ×ÏÚ×ÒÁÔÏ× if ((RS_TICKS)-11) eq 28 ; 38400 and 6MHz call _x2 ;28=2+2*13 _x2: nop call _x1 ;12=2+2*5 _x1: nop brake elseif ((RS_TICKS)-11) eq 67 ; 19200 and 6MHz if 0 nop call _x1 ;66=2*3+4*15 call _x1 ; call _x1 ;66=2*5+10+10+10+10+10+6 call _x1 ; call _x2 ; _x1: brake brake _x2: brake brake else TEMP_DELAY = TEMP_0 clrf TEMP_DELAY bsf TEMP_DELAY,4 _tx_delay: nop decfsz TEMP_DELAY,F jump _tx_delay endif else error endif _delay4: return _c_is_clear: bsf B_RS232_TxD ; 1 addlw 10h ; 1 bcf C ; 1 =nop jump _tx_loop ; 2 ;======================================================================== ; ;======================================================================== _init: ;movlw 00000000b ; RS232_TxD:=0, RS232_CTS:=0 clrf PORTB ; clrf PORTA movlw 00000000b ; porta, ___ooooo tris 5 movlw 00000001b ; portb, oooooooi tris 6 bcf B_TCP_ONLINE ; tcp_online=0 _error: clrf IP_HLEN ; bsf B_SLIP_OUTPKT ; at first outside of the package ; ÓÎÁÞÁÌÁ ÓÎÁÒÕÖÉ ÐÁËÅÔÁ _rx: bsf B_RS232_CTS ; raise CTS ÐÏÄÎÑÔØ CTS movlw 10010000b ; GIE+INTE movwf INTCON _rxl: ; clrwdt ;???? jump _rxl ;======================================================================== ; Sending of the TCP/IP package ÐÅÒÅÄÁÞÁ TCP/IP ÐÁËÅÔÁ ;======================================================================== _just_ack: _tcp_send_empty_10: bcf TCPS_FLAG,0 ; TCPS_FLAG=xxxxxxx0 bcf TCPS_FLAG,1 ; TCPS_FLAG=xxxxxx0x _tcp_send_empty: clrf TCPS_LEN _tcp_send: call _tx_slip_end SUM0 <-(4500h+4000h+8000h)> ; calculation of the IP header control sum ; ÒÁÓÞÅÔ ËÏÎÔÒÏÌØÎÏÊ ÓÕÍÍÙ IP ÚÁÇÏÌÏ×ËÁ movwf IP_SUM_0 SUM1 <-(4500h+4000h+8000h)> movwf IP_SUM_1 TXLW 045h call _tx_0_0 movf TCPS_LEN,W addlw 14h+14h movwf IP_LEN ; IP_LEN = TCPS_LEN+14h+14h call _slitx call _chksum_pseudoheader call _tx_0_0 TXLW 040h call _tx_0 TXLW 080h TXLW 006h call _slitx_csum SLITXLW ADDR_MYSELF_0 SLITXLW ADDR_MYSELF_1 SLITXLW ADDR_MYSELF_2 SLITXLW ADDR_MYSELF_3 movlw IP_ADR_0 call _slitx4 movf TCPR_SEQ_L0,W ; SEQ formatting for the TCP package which is ; being sent ; ÆÏÒÍÉÒÏ×ÁÎÉÅ SEQ ÄÌÑ subwf TCPS_ACK,W ; ÏÔÐÒÁ×ÌÑÅÍÏÇÏ TCP ÐÁËÅÔÁ jc _no_correct_hi_seq ; incf TCPR_SEQ_L1,F ; skipnz ; incf TCPR_SEQ_L2,F skipnz incf TCPR_SEQ_L3,F _no_correct_hi_seq: addwf TCPR_SEQ_L0,F ; TCPR_SEQ_L0+=TCPS_ACK-TCPR_SEQ_L0 SUM0 <-(5000h+TCP_RCV_WINDOW-0014h)> movwf IP_SUM_0 ; calculation of the TCP headers control sum ; ÒÁÓÞÅÔ ËÏÎÔÒÏÌØÎÏÊ ÓÕÍÍÙ TCP ÚÁÇÏÌÏ×ËÁ SUM1 <-(5000h+TCP_RCV_WINDOW-0014h)> movwf IP_SUM_1 call _chksum_pseudoheader movlw TCPR_LPORT_H movwf FSR call _slitx2 movlw TCPR_RPORT_H movwf FSR call _slitx2 movlw TCPR_ACK_L3 call _slitx4 movlw TCPR_SEQ_L3 call _slitx4 TXLW 050h movf TCPS_FLAG,W andlw 00010011b ; 0x10,0x11,0x12 call _tx movf TX_BYTE,W call _checksum_lo call _tx_0 TXLW TCP_RCV_WINDOW clrf IP_POS _loop_top0: movf TCPS_LEN,W ; calculation of the TCP package's body ; ÒÁÓÞÅÔ ËÏÎÔÒÏÌØÎÏÊ ÓÕÍÍÙ xorwf IP_POS,W ; ÔÅÌÁ TCP ÐÁËÅÔÁ jz _loop_break0 call _file_read call _checksum_byte incf IP_POS,F jump _loop_top0 _loop_break0: call _slitx_csum call _tx_0_0 clrf IP_POS ; delivery of the TCP package's body ; ÐÅÒÅÄÁÞÁ ÔÅÌÁ TCP ÐÁËÅÔÁ _loop_top1: movf TCPS_LEN,W xorwf IP_POS,W jz _loop_break1 call _file_read call _slitx incf IP_POS,F jump _loop_top1 _loop_break1: _tx_slip_end: movlw 0C0h ; deliver SLIP.END ÐÅÒÅÄÁÔØ SLIP.END jump _tx ;======================================================================== ; calculation/check of control sums of TCP/IP headers/packages ; ÒÁÓÞÅÔ/ÐÒÏ×ÅÒËÁ ËÏÎÔÒÏÌØÎÙÈ ÓÕÍÍ TCP/IP ÚÁÇÏÌÏ×ËÏ×/ÐÁËÅÔÏ× ;======================================================================== _chksum_pseudoheader: movf IP_LEN,W call _checksum_lo movf IP_ADR_0,W call _checksum_hi movf IP_ADR_1,W call _checksum_lo movf IP_ADR_2,W call _checksum_hi movf IP_ADR_3,W call _checksum_lo SUM0 <6+((ADDR_MYSELF_0+ADDR_MYSELF_2)shl 8)+(ADDR_MYSELF_1+ADDR_MYSELF_3)> call _checksum_hi SUM1 <6+((ADDR_MYSELF_0+ADDR_MYSELF_2)shl 8)+(ADDR_MYSELF_1+ADDR_MYSELF_3)> jump _checksum_lo ;------------------------------------------ _checksum_byte: j1 <IP_POS,0>,_checksum_lo _checksum_hi: subwf IP_SUM_0,F ; correct high byte of the control sum ; ËÏÒÒÅËÔÉÒÏ×ÁÔØ ÓÔ.ÂÁÊÔ ËÏÎÔÒ.ÓÕÍÍÙ movlw 1 skipc _checksum_lo: subwf IP_SUM_1,F ; correct low byte of the control sum ; ËÏÒÒÅËÔÉÒÏ×ÁÔØ ÍÌ.ÂÁÊÔ ËÏÎÔÒ.ÓÕÍÍÙ movlw 1 skipc subwf IP_SUM_0,F skipc subwf IP_SUM_1,F return ;======================================================================== ; UDP handler ;======================================================================== _process_udp: ; ... to do ... ;======================================================================== ; TCP handler ;======================================================================== _process_tcp: movf TCPR_LPORT_L,W ; testing the number of the local port ; ÐÒÏ×ÅÒËÁ ÎÏÍÅÒÁ ÌÏËÁÌØÎÏÇÏ ÐÏÒÔÁ xorlw TCP_PORT_HTTP iorwf TCPR_LPORT_H,W skipz return skip0 <TCPR_FLAG,2> ; RST bcf B_TCP_ONLINE j1 <TCPR_FLAG,0>,_tcp_fin ; FIN j1 <TCPR_FLAG,1>,_tcp_syn ; SYN skip1 <TCPR_FLAG,4> ; ACK ???? return ;_tcp_ack: movf TCPS_SEQ,W subwf TCPR_ACK_L0,W subwf TCPS_LEN,W ; TCPS_LEN-TCPR_ACK_L0+TCPS_SEQ jz _my_transmit_is_acked subwf TCPS_LEN,W ; -TCPR_ACK_L0+TCPS_SEQ jz _tcp_send ; if client did not confirm recieve... RETRANSMIT!! ; ÅÓÌÉ ËÌÉÅÎÔ ÎÅ ÐÏÄÔ×ÅÒÄÉÌ ÐÒÉÅÍ... RETRANSMIT !!!! return ; completely wrong TCPR_ACK_L0 = we're not responding ; ÓÏ×ÓÅÍ ÎÅÐÒÁ×ÉÌØÎÙÊ TCPR_ACK_L0 = ÎÅ ÏÔ×ÅÞÁÅÍ _my_transmit_is_acked: movf TCPR_ACK_L0,W ; tcps_seq=LO(tcpr.ack); movwf TCPS_SEQ ; movf TCPR_SEQ_L0,W ; if(tcpr.seq==tcps_ack1) xorwf TCPS_ACK,W ; jnz _tcp_send ; if we havn't RX'd what we expected... RETRANSMIT! ; ÅÓÌÉ ÍÙ ÐÏÌÕÞÉÌÉ ÎÅ ÔÏ, ÞÔÏ ÖÄÁÌÉ... RETRANSMIT !!!! ;_new_data_was_rvcd: movf TCPR_HLEN,W subwf IP_LEN,W addwf TCPS_ACK,F ; tcps_ack1 += ip_len-tcpr.hlen; addwf TCPR_POS,F skipnc bsf TCPR_POS,7 ; 0-->](128..255) ;;****** HTTP server ËÁË ËÏÎÅÞÎÙÊ Á×ÔÏÍÁÔ ******************* movlw 00010001b ; http_state = * ; b_tcp_online = 0 ; tcps_flag = FIN+ACK j1 B_HTTP_STATE_1,_set_flag_and_send j1 B_HTTP_STATE_0,_http_state_1 _http_state_0: movf TCPR_POS,W ; if(tcpr_pos<*) goto _tcp_send_empty_10 addlw -8 ; *** ; strlen("GET / HTTP/0.9\r\n\r\n")=18 jnc _tcp_send_empty_10 ; ??? todo: file system functions ;=set http_unitidx ;=set http_filesize_h ;=set http_filesize_l if FS_USE_INTERNAL_ROM ;------------------------ ; CGI ;------------------------ movf HTTP_NAME_0,W sublw 'a' ; jz _cgi_a ; HTTP_NAME_0 == 'a' sublw <'a'-'0'> ; addlw -10 ; jnc _cgi_digit ; HTTP_NAME_0 in ['0'..'9'] movlw 3 ; movwf HTTP_UNITIDX ; HTTP_UNITIDX = 3 clrf HTTP_FILESIZE_H ; movlw 068h ; HTTP_FILESIZE = 0x6E jump _cgi_done ; _cgi_digit: rlf HTTP_NAME_1,F ; status.c=0 movf HTTP_NAME_1,W ; rlf HTTP_NAME_1,F ; rlf HTTP_NAME_1,F ; addwf HTTP_NAME_1,W ; addwf HTTP_NAME_2,W ; W := 10*HTTP_NAME_0+HTTP_NAME_1 addlw -16 ; W := 10*(HTTP_NAME_0-'0')+(HTTP_NAME_1-'0') skip0 <HTTP_NAME_0,0> addlw 100 skip0 <HTTP_NAME_0,1> addlw 200 movwf PORTB ; ; andlw 11110b ; movwf PORTB ; _cgi_a: clrf HTTP_UNITIDX ; HTTP_UNITIDX = 0 movlw 1 ; movwf HTTP_FILESIZE_H ; HTTP_FILESIZE = 0x180 movlw 080h ; _cgi_done: movwf HTTP_FILESIZE_L ; endif if FS_USE_EXTERNAL_ROM ...todo... endif bsf B_HTTP_STATE_0 ; http_state=1 jump _send_portion_of_file _http_state_1: incf HTTP_UNITIDX,F ; http_unitidx++ movf TCPS_LEN,W ; http_filesize -= tcps_len; subwf HTTP_FILESIZE_L,F skipc decf HTTP_FILESIZE_H,F _send_portion_of_file: movf HTTP_FILESIZE_H,F jnz _transmit_80 movf HTTP_FILESIZE_L,W addlw 7Fh jc _transmit_80 bsf B_HTTP_STATE_1 ; http_state=3 movf HTTP_FILESIZE_L,W ; <== TRANSMIT less than TCP_SND_WINDOW bytes jump _transmit_not_80 _transmit_80: movlw TCP_SND_WINDOW ; <== TRANSMIT TCP_SND_WINDOW bytes _transmit_not_80: movwf TCPS_LEN jump _tcp_send _tcp_fin: incf TCPR_SEQ_L0,W ; tcps_ack1 = B3(tcpr.seq)+1; movwf TCPS_ACK incf TCPS_SEQ,F ; tcps_seq1++; movlw 00010000b ; tcps_flag = 0x11; // SYN+ACK ; tcp_online=0; ; http_state=*; _set_flag_and_send: movwf TCPS_FLAG jump _tcp_send_empty ; tcp_send_empty(); // 0 byte ÐÅÒÅÄÁÅÍ 0 ÂÁÊÔ _tcp_syn: ;; j1 B_TCP_ONLINE,_return ; if( 0==tcp_online ) { incf TCPR_SEQ_L0,W ; tcps_ack1 = B3(tcpr.seq)+1; movwf TCPS_ACK clrf TCPR_POS ; tcpr_pos=0; clrf TCPS_SEQ ; tcps_seq1=ISS=0; movlw 10010010b ; http_state=0; // just connected movwf TCPS_FLAG ; tcps_flag = 0x12; // SYN+ACK call _tcp_send_empty ; tcp_send_empty(); // ÐÅÒÅÄÁÅÍ 0 ÂÁÊÔ incf TCPS_SEQ,F ; tcps_seq1++; return ; } if FS_USE_INTERNAL_ROM ;======================================================================== ; Internal ROM/EEPROM File (max 512/64 bytes) ;======================================================================== ; UNIT0: ROM 0x0200..0x027F ; UNIT1: ROM 0x0280..0x02FF ; UNIT2: ROM 0x0300..0x037F ; UNIT3: ROM 0x0380..0x03FF ; UNIT4: EEPROM 0x0000..0x003F ;======================================================================== _file_read: if FS_USE_INTERNAL_EEPROM j0 <HTTP_UNITIDX,2>,_ir_read _ie_read: movf IP_POS,W movwf EEADR ; Address to read bsf RP0 bsf EECON1,0 ; EE Read bcf RP0 movf EEDATA,W ; W = EEDATA return endif _ir_read: clrf PCLATH bsf PCLATH,1 if FS_INTERNAL_ROM_UNITS ge 2 skip0 <HTTP_UNITIDX,1> bsf PCLATH,0 endif movf IP_POS,W if FS_INTERNAL_ROM_UNITS ge 1 skip0 <HTTP_UNITIDX,0> iorlw 80h endif movwf PCL ;======================================================================== ; Simple CGI support :) ;======================================================================== _cgi_portb_hi: swapf PORTB,W jump _lo4bit_as_hexdigit ; skip0 <PORTA,4> ; retlw '1' ; retlw '0' _cgi_portb_lo: movf PORTB,W _lo4bit_as_hexdigit: andlw 00001111b addlw -10 skipnc addlw 7 addlw 58 return .org 800h ;======================================================================== ; JavaScript program for PortB control ;======================================================================== .db 'H','T','T','P','/','1','.','0',' ','2','0','0', 13, 10, 13, 10 ; "Content-Type: %s", "blah-blah-blah" ; "Content-Length: %d", blah_blah_blah ; "Refresh: %d", blah_blah_blah .db '<','t','i','t','l','e','>','P','o','r','t',' ','B','<','/','t' .db 'i','t','l','e','>','<','b','o','d','y',' ','o','n','L','o','a' .db 'd','=','"','f','o','r','(','v','a','r',' ','i','=','0',';','i' .db '<','7',';','i','+','+',')','d','o','c','u','m','e','n','t','.' .db 'f','o','r','m','s','[','0',']','.','e','l','e','m','e','n','t' .db 's','[','i',']','.','c','h','e','c','k','e','d','=','0','x' jump _cgi_portb_hi ; SIC! jump _cgi_portb_lo .db '&','(','2','<','<','i',')','"','>','<','f','o','r','m',' ' .db 'a','c','t','i','o','n','=','a','>','<','s','c','r','i','p','t' .db '>','f','o','r','(','v','a','r',' ','i','=','1',';','i','<','8' .db ';','i','+','+',')','d','o','c','u','m','e','n','t','.','w','r' .db 'i','t','e','(','"','B','.','"','+','i','+','"','<','I','N','P' .db 'U','T',' ','T','Y','P','E','=','c','h','e','c','k','b','o','x' .db '>','<','B','R','>','"',')','<','/','s','c','r','i','p','t','>' .db '<','i','n','p','u','t',' ','t','y','p','e','=','s','u','b','m' .db 'i','t',' ','v','a','l','u','e','=','R','e','a','d','>','<','i' .db 'n','p','u','t',' ','t','y','p','e','=','b','u','t','t','o','n' .db ' ','v','a','l','u','e','=','W','r','i','t','e',' ','o','n','C' .db 'l','i','c','k','=','"','f','o','r','(','v','a','r',' ','v','=' .db '4','0','0',',','i','=','0',';','i','<','7',';','v','+','=','d' .db 'o','c','u','m','e','n','t','.','f','o','r','m','s','[','0',']' .db '.','e','l','e','m','e','n','t','s','[','i',']','.','c','h','e' .db 'c','k','e','d','<','<','+','+','i',')',';','t','o','p','.','l' .db 'o','c','a','t','i','o','n','.','h','r','e','f','=','v','"','>' ; .db 'H','T','T','P','/','1','.','0',' ','4','0','4', 13, 10, 13, 10 ; .db 'N','o','t',' ','f','o','u','n','d','<','h','r','>','<','a',' ' ; .db 'h','r','e','f','=','i','>','M','a','i','n',' ','P','a','g','e' ; .db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ; .db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ; .db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ; .db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ; .db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 .db 'H','T','T','P','/','1','.','0',' ','2','0','0', 13, 10, 13, 10 .db '<','a',' ','h','r','e','f','=','a','>','P','o','r','t','B',' ' .db 'c','o','n','t','r','o','l','<','/','a','>','<','h','r','>','<' .db 'a',' ','h','r','e','f','=','h','t','t','p',':','/','/','z','h' .db 'e','n','g','x','i','.','d','a','.','r','u','>','D','e','n','i' .db 's',' ','P','e','t','r','o','v',27h,'s',' ','h','o','m','e',' ' .db 'p','a','g','e','<','/','a','>', 0, 0, 0, 0, 0, 0, 0, 0 .db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 endif if FS_USE_EXTERNAL_ROM _file_read: retlw 0 endif end |
file: /Techref/piclist/petrovwwwpic/pic2.htm, 137KB, , updated: 2006/3/5 18:10, local time: 2024/8/14 12:52,
3.142.197.212:LOG IN
|
©2024 These pages are served without commercial sponsorship. (No popup ads, etc...).Bandwidth abuse increases hosting cost forcing sponsorship or shutdown. This server aggressively defends against automated copying for any reason including offline viewing, duplication, etc... Please respect this requirement and DO NOT RIP THIS SITE. Questions? <A HREF="http://massmind.org/techref/piclist/petrovwwwpic/pic2.htm"> Denis Petrovs home page</A> |
Did you find what you needed? |
Welcome to massmind.org! |
Ashley Roll has put together a really nice little unit here. Leave off the MAX232 and keep these handy for the few times you need true RS232! |
.