Subversion Repositories Kolibri OS

Compare Revisions

Regard whitespace Rev 4655 → Rev 4654

/programs/network/tftpc/tftpc.asm
14,9 → 14,6
 
format binary as ""
 
__DEBUG__ = 0
__DEBUG_LEVEL__ = 1
 
use32
org 0x0
 
35,16 → 32,17
include '../../develop/libraries/box_lib/trunk/box_lib.mac'
 
include '../../network.inc'
include '../../debug-fdo.inc'
 
 
filebuffer_size = 4*4096 ; 16kb (dont try to change it yet..)
TIMEOUT = 100
buffer_len = 4096
buffer_len = 1500
 
opcode_rrq = 1 shl 8
opcode_wrq = 2 shl 8
opcode_data = 3 shl 8
opcode_ack = 4 shl 8
opcode_error = 5 shl 8
opcode_rrq = 1
opcode_wrq = 2
opcode_data = 3
opcode_ack = 4
opcode_error = 5
 
; read/write request packet
;
83,18 → 81,22
or eax, eax
jnz exit
 
home:
stop_transfer:
mcall 40, EVM_MOUSE + EVM_MOUSE_FILTER + EVM_REDRAW + EVM_BUTTON + EVM_KEY + EVM_STACK
 
redraw:
red_win:
call draw_window
 
mainloop:
align 4
still:
mcall 10
 
dec eax
jz redraw
jz red_win
 
dec eax
jz key
 
dec eax
jz button
 
106,7 → 108,7
invoke option_box_mouse, Option_boxs1
invoke option_box_mouse, Option_boxs2
 
jmp mainloop
jmp still
 
button:
mcall 17
115,7 → 117,7
je start_transfer
 
test ah , ah
jz mainloop
jz still
 
exit:
mcall -1
127,7 → 129,7
invoke edit_box_key, edit3
invoke edit_box_key, edit4
 
jmp mainloop
jmp still
 
 
draw_window:
174,50 → 176,31
mov esi, [sc.work_button]
mcall 8, 210 shl 16 + 170, 105 shl 16 + 16, 0x10
 
mcall 38, 10 shl 16 + 380, 130 shl 16 + 130, [sc.work_graph]
 
cmp [errormsg], 0
je .no_error
 
mov ecx, 0x80000000
or ecx, [sc.work_text]
mcall 4, 20 shl 16 + 137, , [errormsg]
mcall 12, 2
jmp .draw_btn
or ecx, [sc.work_button_text]
mcall 4, 260 shl 16 + 110, , str_transfer
 
.no_error:
mov ecx, 0x80000000
or ecx, [sc.work_text]
mcall 4, 350 shl 16 + 137, , str_kb_s
mcall 4, 50 shl 16 + 137, , str_complete
mcall 47, 1 shl 31 + 7 shl 16 + 1, kbps, 305 shl 16 + 137, [sc.work_text]
mcall 47, 1 shl 31 + 3 shl 16 + 1, done, 25 shl 16 + 137
 
.draw_btn:
cmp [socketnum], 0
je .no_transfer
mcall 38, 10 shl 16 + 380, 130 shl 16 + 130, [sc.work_graph]
 
mov ecx, 0x80000000
or ecx, [sc.work_button_text]
mcall 4, 270 shl 16 + 110, , str_stop
mcall 47, 1 shl 31 + 7 shl 16 + 1, kbps, 305 shl 16 + 137, [sc.work_text]
mcall 47, 1 shl 31 + 3 shl 16 + 1, done, 25 shl 16 + 137, ;[sc.work_text]
 
mcall 12, 2
 
ret
 
.no_transfer:
mov ecx, 0x80000000
or ecx, [sc.work_button_text]
mcall 4, 260 shl 16 + 110, , str_transfer
 
mcall 12, 2
ret
 
 
 
start_transfer:
 
; resolve the hostname
mov [errormsg], str_err_resolve
; first, resolve the hostname
 
push esp ; reserve stack place
 
231,320 → 214,225
 
; test for error
test eax, eax
jnz home
jnz still
 
mov eax, [esi + addrinfo.ai_addr]
mov eax, [eax + sockaddr_in.sin_addr]
mov [sockaddr.ip], eax
mov esi, [esi]
mov esi, [esi + sockaddr_in.sin_addr]
mov dword [IP], esi
 
; free allocated memory
push esi
call [freeaddrinfo]
mcall socket, AF_INET4, SOCK_DGRAM, 0 ; socket_open
cmp eax, -1
je still
 
; Open a socket & connect to server
mov [errormsg], str_err_socket
 
mcall socket, AF_INET4, SOCK_DGRAM, 0
cmp eax, -1
je home
mov [socketnum], eax
 
mcall connect, [socketnum], sockaddr, sockaddr_len
mcall connect, [socketnum], sockaddr, sockaddr_len ; socket_connect
cmp eax, -1
je home
je still
 
; Create the read/write request packet
mov word[buffer], opcode_rrq
mov word [I_END], opcode_rrq
cmp [option_group2], op3
je @f
mov word[buffer], opcode_wrq
mov word [I_END], opcode_wrq
@@:
 
; Copy in the remote filename (asciiz)
xor al, al
mov edi, remote_addr
mov ecx, 255
mov ecx, 250
repnz scasb
lea ecx, [edi - remote_addr - 1]
sub edi, remote_addr-1
mov ecx, edi
mov edi, I_END+2
mov esi, remote_addr
mov edi, buffer+2
rep movsb
stosb
 
; Append the data type (asciiz)
cmp [option_group1], op1
je .ascii
 
mov esi, octet
movsd
movsb
 
jmp .send_request
 
.ascii:
 
mov esi, netascii
movsd
movsd
 
; Send the request to the server
.send_request:
 
xor al, al
stosb
lea esi, [edi - buffer]
xor edi, edi
mcall send, [socketnum], buffer
cmp eax, -1
je home
 
; Jump to send/receive code
cmp word[buffer], opcode_wrq
je tftp_send
sub edi, I_END
mov esi, edi
mcall send, [socketnum], I_END
 
mcall 40, EVM_REDRAW + EVM_BUTTON + EVM_STACK
 
tftp_receive:
 
mcall 40, EVM_REDRAW + EVM_BUTTON + EVM_STACK
mov [last_ack], 0
mov [errormsg], 0
 
call draw_window
 
; Open/create local file
mov [file_struct.subfn], 2
mov [file_struct.offset], 0
mov [file_struct.size], 0
mcall 70, file_struct
 
; Truncate it to 0 bytes
mov [file_struct.subfn], 4
mcall 70, file_struct
 
; Set parameters for writing to file
mov [file_struct.subfn], 3
mov [file_struct.data], buffer + 4
receive_data_loop:
 
.loop:
mcall 23, TIMEOUT
 
dec eax
jz .red
 
dec eax
dec eax
jz .button
jz .key
 
 
mcall recv, [socketnum], buffer, buffer_len, MSG_DONTWAIT ; receive data
cmp eax, -1
je .loop
 
DEBUGF 1, "Got %u bytes\n", eax
cmp word[buffer], opcode_error
je tftp_error
cmp word[buffer], opcode_data
jne .error
 
; Verify ACK number
mov bx, word[buffer + 2]
rol bx, 8
cmp [last_ack], 0
je @f
cmp [last_ack], bx
mov bx, [last_ack]
cmp word [buffer + 2], bx
jne .packet_got_lost
inc bx
@@:
mov [last_ack], bx
inc [last_ack]
 
; Write to the file
lea ecx, [eax - 4]
mov [file_struct.size], ecx
mcall 70, file_struct
add [file_struct.offset], ecx
cmp eax, 4+512
je .continue
 
; Send ACK
mov word[buffer], opcode_ack
mcall send, [socketnum], buffer, 4, 0
jmp .loop
; last packet, or something else
.error:
 
.packet_got_lost:
;TODO
jmp .loop
 
 
 
.continue:
 
mov word[buffer], opcode_ack ; send ack
mcall send, [socketnum], buffer, 4, 0
 
jmp receive_data_loop
 
.red:
 
call draw_window
jmp .loop
 
.button:
mcall 17
cmp ah, 1
jne .abort
jmp receive_data_loop
 
mcall close, [socketnum]
mcall -1
 
.abort:
mcall close, [socketnum]
xor eax, eax
mov [socketnum], eax
mov [errormsg], str_abort
jmp home
.key:
mcall 2
cmp ah, 2
jz exit
 
.error:
mcall close, [socketnum]
xor eax, eax
mov [socketnum], eax
mov [errormsg], str_err_unexp
jmp home
; close socket ?
 
.done:
mcall close, [socketnum]
xor eax, eax
mov [socketnum], eax
mov [errormsg], str_success
jmp home
jmp receive_data_loop
 
 
 
tftp_send:
 
mcall 40, EVM_REDRAW + EVM_BUTTON + EVM_STACK
 
 
;--------------------------------
 
 
send_:
 
invoke file_open, local_addr, O_READ
or eax, eax
jz .exit
mov [fh], eax
 
stdcall mem.Alloc, filebuffer_size
or eax, eax
jz .exit
mov [fb], eax
 
mov [last_ack], 0
mov [errormsg], 0
mov [fo], 0
 
call draw_window
.read_chunk:
 
mov [file_struct.subfn], 0
mov [file_struct.offset], 0
mov [file_struct.size], buffer_len
mov [file_struct.data], buffer + 4
invoke file_seek, [fh], [fo], SEEK_END
cmp eax, -1
je .exit
invoke file_read, [fh], [fb], filebuffer_size
cmp eax, -1
je .exit
add [fo], filebuffer_size
cmp eax, filebuffer_size
je .packet
 
.next:
; ijhidfhfdsndsfqk
 
.packet:
 
movzx esi, [last_ack]
and esi, 0x000000001f ; last five bits BUFFER SIZE MUST BE 16 kb for this to work !!!
shl esi, 9 ; = * 512
add esi, [fb]
mov edi, buffer
mov ax, opcode_data
stosw
mov ax, [last_ack]
stosw
mov ecx, 512/4
rep movsd
 
mcall 70, file_struct
test eax, eax
; jnz .done
mov [size], ebx
mcall send, [socketnum], buffer, 4+512, 0 ; send data
 
.resend:
mov ebx, [size]
lea esi, [ebx + 4]
xor edi, edi
mcall send, [socketnum], buffer
 
.loop:
 
mcall 23, TIMEOUT
 
dec eax
jz .red
 
dec eax
dec eax
jz .button
jz .key
 
mcall recv, [socketnum], buffer, buffer_len, MSG_DONTWAIT
cmp eax, -1
je .loop
mcall recv, [socketnum], buffer, buffer_len, MSG_DONTWAIT ; receive ack
 
cmp word[buffer], opcode_error
je tftp_error
cmp word[buffer], opcode_ack
jne .error
jne .exit
 
mov ax, [last_ack]
cmp word[buffer+2], ax
jne .resend
jne .packet
inc [last_ack]
test [last_ack],0x001f
jz .read_chunk
jmp .packet
 
mov eax, [size]
cmp eax, buffer_len
jb .done
add [file_struct.offset], eax
 
inc [last_ack]
jmp .next
.red:
 
.red:
call draw_window
 
jmp .loop
 
.button:
mcall 17
cmp ah, 1
jne .abort
 
mcall close, [socketnum]
mcall -1
.key:
mcall 2
cmp ah, 2
jz exit
 
.abort:
mcall close, [socketnum]
xor eax, eax
mov [socketnum], eax
mov [errormsg], str_abort
jmp home
; close socket ?
 
.error:
mcall close, [socketnum]
xor eax, eax
mov [socketnum], eax
mov [errormsg], str_err_unexp
jmp home
jmp .loop
 
.done:
mcall close, [socketnum]
xor eax, eax
mov [socketnum], eax
mov [errormsg], str_success
jmp home
.exit:
invoke file_close, [fh]
jmp still
 
 
 
tftp_error:
mcall close, [socketnum]
xor eax, eax
mov [socketnum], eax
 
mov ax, word[buffer+2]
xchg al, ah
 
test ax, ax
jz .0
dec ax
jz .1
dec ax
jz .2
dec ax
jz .3
dec ax
jz .4
dec ax
jz .5
dec ax
jz .6
dec ax
jz .7
 
.0:
mov [errormsg], str_error.0
jmp home
.1:
mov [errormsg], str_error.1
jmp redraw
.2:
mov [errormsg], str_error.2
jmp home
.3:
mov [errormsg], str_error.3
jmp home
.4:
mov [errormsg], str_error.4
jmp home
.5:
mov [errormsg], str_error.5
jmp home
.6:
mov [errormsg], str_error.6
jmp home
.7:
mov [errormsg], str_error.7
jmp home
 
;-------------------------
; DATA
 
551,27 → 439,19
socketnum dd 0
kbps dd 0
done dd 0
errormsg dd str_welcome
 
sockaddr:
dw AF_INET4
dw 0x4500 ; 69
.ip dd ?
IP db 192, 168, 1, 115
 
sockaddr_len = $ - sockaddr
 
file_struct:
.subfn dd ?
.offset dd ?
dd 0
.size dd ?
.data dd ?
db 0
.filename dd local_addr
 
align 16
@IMPORT:
 
library box_lib , 'box_lib.obj' ,\
io_lib , 'libio.obj', \
network , 'network.obj'
 
import box_lib ,\
587,6 → 467,21
option_box_mouse, 'option_box_mouse' ,\
version_op , 'version_op'
 
import io_lib ,\
file_find_first , 'file_find_first' ,\
file_find_next , 'file_find_next' ,\
file_find_close , 'file_find_close' ,\
file_size , 'file_size' ,\
file_open , 'file_open' ,\
file_read , 'file_read' ,\
file_write , 'file_write' ,\
file_seek , 'file_seek' ,\
file_tell , 'file_tell' ,\
file_eof? , 'file_iseof' ,\
file_seteof , 'file_seteof' ,\
file_truncate , 'file_truncate' ,\
file_close , 'file_close'
 
import network ,\
inet_ntoa , 'inet_ntoa' ,\
getaddrinfo , 'getaddrinfo' ,\
593,10 → 488,10
freeaddrinfo , 'freeaddrinfo'
 
 
edit1 edit_box 300, 80, 5, 0xffffff, 0x6f9480, 0, 0, 0, 255, SRV, mouse_dd, ed_focus, 13, 13
edit2 edit_box 300, 80, 25, 0xffffff, 0x6f9480, 0, 0, 0, 255, remote_addr, mouse_dd, 0, 4, 4
edit3 edit_box 300, 80, 45, 0xffffff, 0x6f9480, 0, 0, 0, 255, local_addr, mouse_dd, 0, 12, 12
edit4 edit_box 40, 340, 68, 0xffffff, 0x6f9480, 0, 0, 0, 5, BLK, mouse_dd, ed_figure_only, 3, 3
edit1 edit_box 300, 80, 5, 0xffffff, 0x6f9480, 0, 0, 0, 99, SRV, mouse_dd, ed_focus, 13, 13
edit2 edit_box 300, 80, 25, 0xffffff, 0x6a9480, 0, 0, 0, 99, remote_addr, mouse_dd, ed_figure_only, 5, 5
edit3 edit_box 300, 80, 45, 0xffffff, 0x6a9480, 0, 0, 0, 99, local_addr, mouse_dd, ed_figure_only, 27, 27
edit4 edit_box 40, 340, 68, 0xffffff, 0x6a9480, 0, 0, 0, 5, BLK, mouse_dd, ed_figure_only, 3, 3
 
op1 option_box option_group1, 80, 68, 6, 12, 0xffffff, 0, 0, netascii, octet-netascii
op2 option_box option_group1, 80, 85, 6, 12, 0xFFFFFF, 0, 0, octet, get-octet
619,24 → 514,17
str_kb_s db 'kB/s', 0
str_complete db '% complete', 0
str_transfer db 'Transfer', 0
str_stop db 'Stop', 0
 
str_error:
.0 db 'Error.', 0 ; not further defined error
.1 db 'File not found.', 0
.2 db 'Access violation.', 0
.3 db 'Disk full or allocation exceeded.', 0
.4 db 'Illegal TFTP operation.', 0
.5 db 'Unknown transfer ID.', 0
.6 db 'File already exists.', 0
.7 db 'No such user.', 0
._0 db 'Not defined, see error message (if any).', 0
._1 db 'File not found.', 0
._2 db 'Access violation.', 0
._3 db 'Disk full or allocation exceeded.', 0
._4 db 'Illegal TFTP operation.', 0
._5 db 'Unknown transfer ID.', 0
._6 db 'File already exists.', 0
._7 db 'No such user.', 0
 
str_welcome db 'Welcome.', 0
str_err_resolve db 'Unable to resolve server address.', 0
str_err_socket db 'Socket error.', 0
str_err_unexp db 'Unexpected command from server.', 0
str_success db 'Operation completed successfully.', 0
str_abort db 'Operation aborted by user.', 0
 
netascii db 'NetASCII'
octet db 'Octet'
645,25 → 533,26
 
BLK db "512", 0, 0, 0
 
last_ack dw ?
 
fh dd ? ; file handle
fo dd ? ; file offset
fb dd ? ; file buffer
 
SRV db "192.168.1.115", 0
rb (SRV + 256 - $)
 
remote_addr db "file", 0
remote_addr db "IMG00", 0
rb (remote_addr + 256 - $)
 
local_addr db "/tmp0/1/file", 0
local_addr db "/hd0/1/KolibriOS/kernel.mnt", 0
rb (local_addr + 256 - $)
 
include_debug_strings
 
I_END:
 
last_ack dw ?
size dd ?
mouse_dd dd ?
 
sc system_colors
 
mouse_dd dd ?
buffer rb buffer_len
 
IM_END: