mirror of
https://github.com/bobbimanners/emailler.git
synced 2024-11-18 21:07:03 +00:00
273 lines
5.0 KiB
ArmAsm
273 lines
5.0 KiB
ArmAsm
|
;########################
|
||
|
; minimal tcp implementation
|
||
|
; written by jonno@jamtronix.com 2009
|
||
|
;########################
|
||
|
|
||
|
.include "../inc/common.i"
|
||
|
|
||
|
MAX_TCP_RETRY=10
|
||
|
|
||
|
.export tcp_init
|
||
|
.export tcp_process
|
||
|
.export tcp_connect
|
||
|
; .export tcp_close
|
||
|
.export tcp_send
|
||
|
|
||
|
.export tcp_callback
|
||
|
|
||
|
.export tcp_inp
|
||
|
.export tcp_outp
|
||
|
|
||
|
.exportzp tcp_src_port
|
||
|
.exportzp tcp_dest_port
|
||
|
; .exportzp tcp_len
|
||
|
.exportzp tcp_cksum
|
||
|
.exportzp tcp_data
|
||
|
|
||
|
.export tcp_send_dest
|
||
|
.export tcp_send_src_port
|
||
|
.export tcp_send_dest_port
|
||
|
.export tcp_send_len
|
||
|
|
||
|
|
||
|
.import ip65_process
|
||
|
.import timer_read
|
||
|
.import ip_calc_cksum
|
||
|
.import ip_send
|
||
|
.import ip_create_packet
|
||
|
.import ip_inp
|
||
|
.import ip_outp
|
||
|
.importzp ip_cksum_ptr
|
||
|
.importzp ip_header_cksum
|
||
|
.importzp ip_src
|
||
|
.importzp ip_dest
|
||
|
.importzp ip_data
|
||
|
.importzp ip_proto
|
||
|
.importzp ip_proto_tcp
|
||
|
.importzp ip_id
|
||
|
.importzp ip_len
|
||
|
|
||
|
.import copymem
|
||
|
.importzp copy_src
|
||
|
.importzp copy_dest
|
||
|
|
||
|
.import cfg_ip
|
||
|
|
||
|
|
||
|
.bss
|
||
|
|
||
|
; arguments for tcp_connect
|
||
|
tcp_callback: .res 2
|
||
|
tcp_send_dest: .res 4
|
||
|
tcp_send_src_port: .res 2
|
||
|
tcp_send_dest_port: .res 2
|
||
|
|
||
|
;data on current connection
|
||
|
tcp_current_seq_number: .res 4
|
||
|
tcp_last_ack_number: .res 4
|
||
|
tcp_expected_ack_number: .res 4
|
||
|
tcp_flags_value: .res 1
|
||
|
|
||
|
; arguments for tcp_send
|
||
|
tcp_send_len: .res 2
|
||
|
|
||
|
; tcp packet offsets
|
||
|
tcp_inp = ip_inp + ip_data
|
||
|
tcp_outp = ip_outp + ip_data
|
||
|
tcp_src_port = 0
|
||
|
tcp_dest_port = 2
|
||
|
tcp_sequence_number=4
|
||
|
tcp_ack_number=8
|
||
|
tcp_flags=12
|
||
|
tcp_window_size=14
|
||
|
tcp_cksum = 16
|
||
|
tcp_urgent_pointer = 18
|
||
|
tcp_data=20
|
||
|
|
||
|
|
||
|
tcp_state: .res 1
|
||
|
tcp_state_listen=1
|
||
|
tcp_state_syn_sent=2
|
||
|
tcp_state_syn_received=3
|
||
|
tcp_state_established=4
|
||
|
tcp_state_fin_wait_1=5
|
||
|
tcp_state_fin_wait_2=6
|
||
|
tcp_state_close_wait=7
|
||
|
tcp_state_closing=8
|
||
|
tcp_state_last_ack=9
|
||
|
tcp_state_time_wait=10
|
||
|
tcp_state_closed=11
|
||
|
|
||
|
tcp_message_sent_count: .res 1
|
||
|
tcp_loop_count: .res 1
|
||
|
tcp_timer: .res 1
|
||
|
|
||
|
; virtual header
|
||
|
tcp_vh = tcp_outp - 12
|
||
|
tcp_vh_src = 0
|
||
|
tcp_vh_dest = 4
|
||
|
tcp_vh_zero = 8
|
||
|
tcp_vh_proto = 9
|
||
|
tcp_vh_len = 10
|
||
|
|
||
|
.code
|
||
|
|
||
|
; initialize tcp
|
||
|
tcp_init:
|
||
|
;nothing to do here yet
|
||
|
rts
|
||
|
|
||
|
|
||
|
; process incoming tcp packet
|
||
|
tcp_process:
|
||
|
rts
|
||
|
|
||
|
|
||
|
;connect to a remote server
|
||
|
; but first:
|
||
|
;
|
||
|
; set destination address
|
||
|
; set source port
|
||
|
; set destination port
|
||
|
; set callback address
|
||
|
|
||
|
tcp_connect:
|
||
|
ldax #0
|
||
|
stax tcp_send_len
|
||
|
sta tcp_message_sent_count
|
||
|
lda #$02 ;SYN
|
||
|
sta tcp_flags_value
|
||
|
lda #tcp_state_syn_sent
|
||
|
sta tcp_state
|
||
|
|
||
|
jsr tcp_send
|
||
|
|
||
|
@tcp_polling_loop:
|
||
|
lda tcp_message_sent_count
|
||
|
adc #1
|
||
|
sta tcp_loop_count ;we wait a bit longer between each resend
|
||
|
@outer_delay_loop:
|
||
|
jsr timer_read
|
||
|
stx tcp_timer ;we only care about the high byte
|
||
|
|
||
|
@inner_delay_loop:
|
||
|
jsr ip65_process
|
||
|
lda tcp_state
|
||
|
cmp #tcp_state_syn_sent
|
||
|
clc
|
||
|
bne @done
|
||
|
jsr timer_read
|
||
|
cpx tcp_timer ;this will tick over after about 1/4 of a second
|
||
|
beq @inner_delay_loop
|
||
|
|
||
|
dec tcp_loop_count
|
||
|
bne @outer_delay_loop
|
||
|
|
||
|
jsr tcp_send
|
||
|
inc tcp_message_sent_count
|
||
|
lda tcp_message_sent_count
|
||
|
cmp #MAX_TCP_RETRY-1
|
||
|
bpl @too_many_retries
|
||
|
jmp @tcp_polling_loop
|
||
|
|
||
|
@too_many_retries:
|
||
|
sec
|
||
|
@done:
|
||
|
rts
|
||
|
|
||
|
|
||
|
; send tcp packet to currently open connection
|
||
|
;
|
||
|
; but first:
|
||
|
;
|
||
|
; set length
|
||
|
|
||
|
tcp_send:
|
||
|
stax copy_src ; copy data to output buffer
|
||
|
ldax #tcp_outp + tcp_data
|
||
|
stax copy_dest
|
||
|
ldax tcp_send_len
|
||
|
jsr copymem
|
||
|
|
||
|
|
||
|
lda tcp_flags_value
|
||
|
sta ip_outp +tcp_flags
|
||
|
|
||
|
ldx #3 ; copy virtual header addresses
|
||
|
: lda tcp_send_dest,x
|
||
|
sta tcp_vh + tcp_vh_dest,x ; set virtual header destination
|
||
|
|
||
|
lda cfg_ip,x
|
||
|
sta tcp_vh + tcp_vh_src,x ; set virtual header source
|
||
|
dex
|
||
|
bpl :-
|
||
|
|
||
|
lda tcp_send_src_port ; copy source port
|
||
|
sta tcp_outp + tcp_src_port + 1
|
||
|
lda tcp_send_src_port + 1
|
||
|
sta tcp_outp + tcp_src_port
|
||
|
|
||
|
lda tcp_send_dest_port ; copy destination port
|
||
|
sta tcp_outp + tcp_dest_port + 1
|
||
|
lda tcp_send_dest_port + 1
|
||
|
sta tcp_outp + tcp_dest_port
|
||
|
|
||
|
lda #ip_proto_tcp
|
||
|
sta tcp_vh + tcp_vh_proto
|
||
|
|
||
|
lda #0 ; clear checksum
|
||
|
sta tcp_outp + tcp_cksum
|
||
|
sta tcp_outp + tcp_cksum + 1
|
||
|
sta tcp_vh + tcp_vh_zero ; clear virtual header zero byte
|
||
|
|
||
|
ldax #tcp_vh ; checksum pointer to virtual header
|
||
|
stax ip_cksum_ptr
|
||
|
|
||
|
lda tcp_send_len ; copy length + 20
|
||
|
clc
|
||
|
adc #20
|
||
|
sta tcp_vh + tcp_vh_len + 1 ; lsb for virtual header
|
||
|
tay
|
||
|
lda tcp_send_len + 1
|
||
|
adc #0
|
||
|
sta tcp_vh + tcp_vh_len ; msb for virtual header
|
||
|
|
||
|
tax ; length to A/X
|
||
|
tya
|
||
|
|
||
|
clc ; add 12 bytes for virtual header
|
||
|
adc #12
|
||
|
bcc :+
|
||
|
inx
|
||
|
:
|
||
|
jsr ip_calc_cksum ; calculate checksum
|
||
|
stax tcp_outp + tcp_cksum
|
||
|
|
||
|
ldx #3 ; copy addresses
|
||
|
: lda tcp_send_dest,x
|
||
|
sta ip_outp + ip_dest,x ; set ip destination address
|
||
|
dex
|
||
|
bpl :-
|
||
|
|
||
|
|
||
|
jsr ip_create_packet ; create ip packet template
|
||
|
|
||
|
|
||
|
lda tcp_outp + tcp_send_len + 1 ; ip len = tcp data len + 20 byte tcp header len + 20 byte ip header len
|
||
|
ldx tcp_outp + tcp_send_len
|
||
|
clc
|
||
|
adc #40
|
||
|
bcc :+
|
||
|
inx
|
||
|
: sta ip_outp + ip_len + 1 ; set length
|
||
|
stx ip_outp + ip_len
|
||
|
|
||
|
ldax #$1234 ; set ID
|
||
|
stax ip_outp + ip_id
|
||
|
|
||
|
lda #ip_proto_tcp ; set protocol
|
||
|
sta ip_outp + ip_proto
|
||
|
|
||
|
|
||
|
jmp ip_send ; send packet, sec on error
|