14,6 → 14,9 |
|
format binary as "" |
|
__DEBUG__ = 0 |
__DEBUG_LEVEL__ = 1 |
|
use32 |
org 0x0 |
|
32,17 → 35,16 |
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 = 1500 |
buffer_len = 4096 |
|
opcode_rrq = 1 |
opcode_wrq = 2 |
opcode_data = 3 |
opcode_ack = 4 |
opcode_error = 5 |
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 |
|
; read/write request packet |
; |
81,22 → 83,18 |
or eax, eax |
jnz exit |
|
stop_transfer: |
home: |
mcall 40, EVM_MOUSE + EVM_MOUSE_FILTER + EVM_REDRAW + EVM_BUTTON + EVM_KEY + EVM_STACK |
|
red_win: |
redraw: |
call draw_window |
|
align 4 |
still: |
mainloop: |
mcall 10 |
|
dec eax |
jz red_win |
|
jz redraw |
dec eax |
jz key |
|
dec eax |
jz button |
|
108,7 → 106,7 |
invoke option_box_mouse, Option_boxs1 |
invoke option_box_mouse, Option_boxs2 |
|
jmp still |
jmp mainloop |
|
button: |
mcall 17 |
117,7 → 115,7 |
je start_transfer |
|
test ah , ah |
jz still |
jz mainloop |
|
exit: |
mcall -1 |
129,7 → 127,7 |
invoke edit_box_key, edit3 |
invoke edit_box_key, edit4 |
|
jmp still |
jmp mainloop |
|
|
draw_window: |
176,31 → 174,50 |
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_button_text] |
mcall 4, 260 shl 16 + 110, , str_transfer |
or ecx, [sc.work_text] |
mcall 4, 20 shl 16 + 137, , [errormsg] |
mcall 12, 2 |
jmp .draw_btn |
|
.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 |
|
mcall 38, 10 shl 16 + 380, 130 shl 16 + 130, [sc.work_graph] |
.draw_btn: |
cmp [socketnum], 0 |
je .no_transfer |
|
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] |
mov ecx, 0x80000000 |
or ecx, [sc.work_button_text] |
mcall 4, 270 shl 16 + 110, , str_stop |
|
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: |
|
; first, resolve the hostname |
; resolve the hostname |
mov [errormsg], str_err_resolve |
|
push esp ; reserve stack place |
|
214,225 → 231,320 |
|
; test for error |
test eax, eax |
jnz still |
jnz home |
|
mov esi, [esi] |
mov esi, [esi + sockaddr_in.sin_addr] |
mov dword [IP], esi |
mov eax, [esi + addrinfo.ai_addr] |
mov eax, [eax + sockaddr_in.sin_addr] |
mov [sockaddr.ip], eax |
|
mcall socket, AF_INET4, SOCK_DGRAM, 0 ; socket_open |
; free allocated memory |
push esi |
call [freeaddrinfo] |
|
; Open a socket & connect to server |
mov [errormsg], str_err_socket |
|
mcall socket, AF_INET4, SOCK_DGRAM, 0 |
cmp eax, -1 |
je still |
|
je home |
mov [socketnum], eax |
|
mcall connect, [socketnum], sockaddr, sockaddr_len ; socket_connect |
mcall connect, [socketnum], sockaddr, sockaddr_len |
cmp eax, -1 |
je still |
je home |
|
mov word [I_END], opcode_rrq |
; Create the read/write request packet |
mov word[buffer], opcode_rrq |
cmp [option_group2],op3 |
je @f |
mov word [I_END], opcode_wrq |
mov word[buffer], opcode_wrq |
@@: |
|
; Copy in the remote filename (asciiz) |
xor al , al |
mov edi, remote_addr |
mov ecx, 250 |
mov ecx, 255 |
repnz scasb |
sub edi, remote_addr-1 |
mov ecx, edi |
mov edi, I_END+2 |
lea ecx, [edi - remote_addr - 1] |
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 |
|
sub edi, I_END |
mov esi, edi |
mcall send, [socketnum], I_END |
; Jump to send/receive code |
cmp word[buffer], opcode_wrq |
je tftp_send |
|
|
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 |
|
receive_data_loop: |
; Set parameters for writing to file |
mov [file_struct.subfn], 3 |
mov [file_struct.data], buffer + 4 |
|
.loop: |
mcall 23, TIMEOUT |
|
dec eax |
jz .red |
|
dec eax |
jz .key |
dec eax |
jz .button |
|
|
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 |
|
mov bx, [last_ack] |
cmp word [buffer + 2], bx |
; Verify ACK number |
mov bx, word[buffer + 2] |
rol bx, 8 |
cmp [last_ack], 0 |
je @f |
cmp [last_ack], bx |
jne .packet_got_lost |
inc [last_ack] |
inc bx |
@@: |
mov [last_ack], bx |
|
cmp eax, 4+512 |
je .continue |
; Write to the file |
lea ecx, [eax - 4] |
mov [file_struct.size], ecx |
mcall 70, file_struct |
add [file_struct.offset], ecx |
|
; last packet, or something else |
.error: |
; Send ACK |
mov word[buffer], opcode_ack |
mcall send, [socketnum], buffer, 4, 0 |
jmp .loop |
|
.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 |
|
jmp receive_data_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 receive_data_loop |
.done: |
mcall close, [socketnum] |
xor eax, eax |
mov [socketnum], eax |
mov [errormsg], str_success |
jmp home |
|
|
|
tftp_send: |
|
|
|
;-------------------------------- |
|
|
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 |
|
mcall 40, EVM_REDRAW + EVM_BUTTON + EVM_STACK |
mov [last_ack], 0 |
mov [fo], 0 |
mov [errormsg], 0 |
|
.read_chunk: |
call draw_window |
|
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 |
mov [file_struct.subfn], 0 |
mov [file_struct.offset], 0 |
mov [file_struct.size], buffer_len |
mov [file_struct.data], buffer + 4 |
|
; 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] |
.next: |
mov edi, buffer |
mov ax, opcode_data |
stosw |
mov ax, [last_ack] |
stosw |
mov ecx, 512/4 |
rep movsd |
|
mcall send, [socketnum], buffer, 4+512, 0 ; send data |
mcall 70, file_struct |
test eax, eax |
; jnz .done |
mov [size], ebx |
|
.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 |
jz .key |
dec eax |
jz .button |
|
mcall recv, [socketnum], buffer, buffer_len, MSG_DONTWAIT ; receive ack |
mcall recv, [socketnum], buffer, buffer_len, MSG_DONTWAIT |
cmp eax, -1 |
je .loop |
|
cmp word[buffer], opcode_error |
je tftp_error |
cmp word[buffer], opcode_ack |
jne .exit |
jne .error |
|
mov ax, [last_ack] |
cmp word[buffer+2], ax |
jne .packet |
jne .resend |
|
mov eax, [size] |
cmp eax, buffer_len |
jb .done |
add [file_struct.offset], eax |
|
inc [last_ack] |
test [last_ack],0x001f |
jz .read_chunk |
jmp .packet |
jmp .next |
|
|
.red: |
|
call draw_window |
|
jmp .loop |
|
.button: |
mcall 17 |
cmp ah, 1 |
jne .abort |
|
.key: |
mcall 2 |
cmp ah, 2 |
jz exit |
mcall close, [socketnum] |
mcall -1 |
|
; close socket ? |
.abort: |
mcall close, [socketnum] |
xor eax, eax |
mov [socketnum], eax |
mov [errormsg], str_abort |
jmp home |
|
jmp .loop |
.error: |
mcall close, [socketnum] |
xor eax, eax |
mov [socketnum], eax |
mov [errormsg], str_err_unexp |
jmp home |
|
.exit: |
invoke file_close, [fh] |
jmp still |
.done: |
mcall close, [socketnum] |
xor eax, eax |
mov [socketnum], eax |
mov [errormsg], str_success |
jmp home |
|
|
|
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 |
|
439,19 → 551,27 |
socketnum dd 0 |
kbps dd 0 |
done dd 0 |
errormsg dd str_welcome |
|
sockaddr: |
dw AF_INET4 |
dw 0x4500 ; 69 |
IP db 192, 168, 1, 115 |
|
.ip dd ? |
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 ,\ |
467,21 → 587,6 |
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' ,\ |
488,10 → 593,10 |
freeaddrinfo , 'freeaddrinfo' |
|
|
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 |
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 |
|
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 |
514,17 → 619,24 |
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 '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 |
.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 |
|
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' |
533,26 → 645,25 |
|
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 "IMG00", 0 |
remote_addr db "file", 0 |
rb (remote_addr + 256 - $) |
|
local_addr db "/hd0/1/KolibriOS/kernel.mnt", 0 |
local_addr db "/tmp0/1/file", 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: |