; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "BSD 2-clause" license.           |
;|_______________________________________________________________________________________|
;
;  Description: OS dependent part of the network library.
;
;  Target OS: KolibriOS
;
;  Dependencies:
;
;  Notes:
;
;  Author: hidnplayr, KolibriOS development team. (c)2012
;
;_________________________________________________________________________________________


body SocketCreate
;.sock dd ?
;.opt  rd 4
begin
        push    ebx ecx edx esi

        mov     eax, sys_socket
        mov     ebx, sockOpen
        mov     ecx, [.protocol_family]
        mov     edx, [.socket_type]
        mov     esi, [.protocol]
        int     $40

;        mov     [.sock], eax

;        cmp     eax, -1
;        je      .finish

;        mov     [.opt], SOL_SOCKET
;        mov     [.opt+4], SO_BLOCK
;        mov     [.opt+8], 1
;
;        mov     ecx, eax
;        mov     eax, sys_socket
;        mov     ebx, sockSetOptions
;        lea     edx, [.opt]
;        int     $40

;        cmp     eax, -1                 ; if eax is -1, set carry flag
;        je      .finish

;        mov     eax, [.sock]

.finish:
        cmp     eax, -1                 ; if eax is -1, set carry flag
        cmc

        pop     esi edx ecx ebx
        return
endp



body SocketClose
begin
        push    ebx ecx

        mov     eax, sys_socket
        mov     ebx, sockClose
        mov     ecx, [.hSocket]
        int     $40

        cmp     eax, -1                 ; if eax is -1, set carry flag
        cmc
        cmovc   eax, ebx                ; eax = error code.

        pop     ecx ebx
        return
endp



body SocketConnect
begin
        push    ebx ecx edx esi

        mov     eax, sys_socket
        mov     ebx, sockConnect
        mov     ecx, [.hSocket]
        mov     edx, [.pAddress]
        mov     esi, sizeof.TSocketAddress
        int     $40

        cmp     eax, -1                 ; if eax is -1, set carry flag
        cmc
        cmovc   eax, ebx                ; eax = error code.

        pop     esi edx ecx ebx
        return
endp



body SocketBind
begin
        push    ebx ecx edx esi

;        stdcall __InternetByteOrder, [.pAddressIn]

        mov     eax, sys_socket
        mov     ebx, sockBind
        mov     ecx, [.hSocket]
        mov     edx, [.pAddressIn]
        mov     esi, sizeof.TSocketAddressIn
        int     $40

        cmp     eax, -1                 ; if eax is -1, set carry flag
        cmc
        cmovc   eax, ebx                ; eax = error code.

        pop     esi edx ecx ebx
        return
endp



body SocketListen
begin
        push    ebx ecx edx

        mov     eax, sys_socket
        mov     ebx, sockListen
        mov     ecx, [.hSocket]
        mov     edx, [.maxPending]
        int     $40

        cmp     eax, -1                 ; if eax is -1, set carry flag
        cmc
        cmovc   eax, ebx                ; eax = error code.

        pop     edx ecx ebx
        return
endp



body SocketAccept
.dummy TSocketAddress
       rb 256
begin
        push    ebx ecx edx esi

        mov     edx, [.pAddress]
        mov     esi, sizeof.TSocketAddress
        test    edx, edx
        cmovz   esi, edx

;        test    edx, edx
;        jnz     .targetok
;        lea     edx, [.dummy]
;.targetok:
        mov     eax, sys_socket
        mov     ebx, sockAccept
        mov     ecx, [.hSocket]
        int     $40

        OutputRegister regEAX, 16

        cmp     eax, -1                 ; if eax is -1, set carry flag
        cmc
        cmovc   eax, ebx                ; eax = error code.

        pop     esi edx ecx ebx
        return
endp



body SocketSend
begin
        push    ebx ecx edx esi edi

.send_loop:
        mov     eax, sys_socket
        mov     ebx, sockSend
        mov     ecx, [.hSocket]
        mov     edx, [.pBuffer]
        mov     esi, [.DataLen]
        mov     edi, [.flags]
        int     $40

        cmp     eax, -1                 ; if eax is -1, set carry flag
        je      .error

        add     [.pBuffer], eax
        sub     [.DataLen], eax
        jnz     .send_loop

        clc

.finish:
        pop     edi esi edx ecx ebx
        return

.error:
        mov     eax, ebx
        stc
        jmp     .finish

endp


body SocketReceive
begin
        push    ebx ecx edx esi edi

        mov     eax, sys_socket
        mov     ebx, sockReceive
        mov     ecx, [.hSocket]
        mov     edx, [.pBuffer]
        mov     esi, [.BufferSize]
        mov     edi, [.flags]
        int     $40

        cmp     eax, -1                 ; if eax is -1, set carry flag
        cmc

        pop     edi esi edx ecx ebx
        return
endp


body SocketSendTo
begin
        stc
        return
endp


body SocketReceiveFrom
begin
        stc
        return
endp





body SocketGetOption
begin
        stc
        return
endp



body SocketSetOption
.opt rd 8
begin
        pushad

        mov     eax, [.idOption]
        mov     ecx, [.Value]

        mov     [.opt], SOL_SOCKET
        mov     [.opt+4], eax
        mov     [.opt+8], 1
        mov     [.opt+12], ecx

        mov     eax, sys_socket
        mov     ebx, sockSetOptions
        mov     ecx, [.hSocket]
        lea     edx, [.opt]
        int     $40

        cmp     eax, -1                 ; if eax is -1, set carry flag
        cmc
        jnc     @f
        mov     [esp+4*regEAX], ebx
@@:
        popad
        return
endp















; Creates pair of IPC sockets and return them in EAX and EDX
; Returns CF=1 on error.

proc SocketPair
begin
        push    ebx

        mov     eax, sys_socket
        mov     ebx, sockPair
        int     $40

        cmp     eax, -1
        cmc

        mov     edx, ebx

        pop     ebx
        return
endp






proc __WaitForNetworkEvent
begin
        pushad

        mov     eax, sys_set_app_param
        mov     ebx, $fffffffe
        int     $40

.loop:
        mov     eax, sys_wait_event_timeout
        mov     ebx, 100
        int     $40

        test    eax, eax
        jz      .timeout

        stdcall Output, "Event accepted: "
        stdcall OutputNumber, eax, 16, 8
        cmp     eax, 8
        jne     .loop

        popad
        return

.timeout:
        DebugMsg "Timeout waiting event."
        jmp      .loop

endp