Files
aqhomecontrol/avr/apps/forwarder/main.asm
Martin Preuss 41843cbab9 avr: added forwarder app.
simpler than router app, just for forwarding messages between interfaces.
mainly used by t03.
2025-08-25 14:12:58 +02:00

360 lines
9.6 KiB
NASM

; ***************************************************************************
; copyright : (C) 2025 by Martin Preuss
; email : martin@libchipcard.de
;
; ***************************************************************************
; * This file is part of the project "AqHome". *
; * Please see toplevel file COPYING of that project for license details. *
; ***************************************************************************
; ***************************************************************************
; defines
; ---------------------------------------------------------------------------
; network interfaces
.equ NETDEV0_IFACENUM = 1
.equ NETDEV1_IFACENUM = 2
; ***************************************************************************
; data
.dseg
; nothing so far
; ***************************************************************************
; code
.cseg
; ---------------------------------------------------------------------------
; @routine AppForwarder_Init @global
AppForwarder_Init:
; set interface number for NETDEV0
ldi r16, NETDEV0_IFACENUM
sts netInterfaceData+NET_IFACE_OFFS_IFACENUM, r16
; set interface number for NETDEV1
ldi r16, NETDEV1_IFACENUM
sts netInterfaceData2+NET_IFACE_OFFS_IFACENUM, r16
sec
ret
; @end
; ---------------------------------------------------------------------------
; @routine AppForwarder_EveryDay @global
;
; @clobbers R16, R17, X
AppForwarder_EveryDay:
ldi yl, LOW(netInterfaceData)
ldi yh, HIGH(netInterfaceData)
bigcall NET_Interface_ResetStats ; (R16, R17, X)
ldi yl, LOW(netInterfaceData2)
ldi yh, HIGH(netInterfaceData2)
bigcall NET_Interface_ResetStats ; (R16, R17, X)
ret
; @end
; ---------------------------------------------------------------------------
; @routine AppForwarder_Run @global
;
; Read messages from either interface and forward to the other one.
AppForwarder_Run:
rjmp appForwarderCheckRecvdMsg
; @end
; ---------------------------------------------------------------------------
; @routine appForwarderCheckRecvdMsg
;
; Read messages from either interface and forward to the other one.
; @return CFLAG set if something done, cleared otherwise
; @clobbers any
appForwarderCheckRecvdMsg:
rcall NET_PeekNextIncomingMsgNum ; check read queue (bufNum->r16)
brcc appForwarderCheckRecvdMsg_ret ; no msg, jmp
rcall NET_Buffer_Locate ; (R17)
push r16
ld r16, X ; read buffer header
andi r16, 0x0f ; keep interface number (in low nibble)
rcall appForwarderGetDeviceByIfaceNum ; Y=src interface (R17)
pop r16
brcc appForwarderCheckRecvdMsg_ret ; interface not found
adiw xh:xl, 1 ; point to message begin
push r16
rcall appForwarderHandleMsgAnyDev ; check for message we should handle (ping etc)
pop r16
; let system handle incoming messages
push r16
rcall appForwarderLetSysHandleMsg
pop r16
; forward to other interface
ldd r17, Y+NET_IFACE_OFFS_IFACENUM
rcall appForwarderSendToOtherDev
brcc appForwarderCheckRecvdMsg_ret ; could not add, jmp
rcall NET_GetNextIncomingMsgNum ; take off the queue
sec
appForwarderCheckRecvdMsg_ret:
ret
; @end
; ---------------------------------------------------------------------------
; @routine appForwarderHandleMsgAnyDev @global
;
; @param Y pointer to source interface for the message
; @param X pointer to received message
; @return CFLAG set if msg handled, cleared otherwise
; @clobbers any, !X
appForwarderHandleMsgAnyDev:
push xl
push xh
rcall appForwarderHandleMsgAnyDev_savedX
pop xh
pop xl
rjmp appForwarderHandleMsgAnyDev_end
appForwarderHandleMsgAnyDev_savedX:
adiw xh:xl, NETMSG_OFFS_CMD ; maybe move ping/reboot handling to all/main.asm?
ld r16, X
sbiw xh:xl, NETMSG_OFFS_CMD
cpi r16, NETMSG_CMD_REBOOT_REQUEST
breq appForwarderHandleMsgAnyDev_handleRebootMsg
cpi r16, NETMSG_CMD_PING
breq appForwarderHandleMsgAnyDev_handlePingMsg
cpi r16, NETMSG_CMD_CLAIM_ADDRESS
breq appForwarderHandleMsgAnyDev_handleClaimAddr
rjmp appForwarderHandleMsgAnyDev_clcRet
appForwarderHandleMsgAnyDev_handleRebootMsg:
rcall appForwarderHandleRebootRequest
ret
appForwarderHandleMsgAnyDev_handlePingMsg:
rcall appForwarderHandlePingRequest
clc
ret
appForwarderHandleMsgAnyDev_handleClaimAddr:
rcall appForwarderHandleClaimAddrRequest
clc
ret
appForwarderHandleMsgAnyDev_clcRet:
clc
appForwarderHandleMsgAnyDev_end:
ret
; @end
; ---------------------------------------------------------------------------
; @routine appForwarderHandleClaimAddrRequest
;
; @param X pointer to received message
; @param Y pointer to source interface for the message
; @clobbers
appForwarderHandleClaimAddrRequest:
rcall NETMSG_Address_Read ; R18=cmd, R19=addr(R18, R19)
lds r16, netInterfaceData+NET_IFACE_OFFS_ADDRESS
cp r19, r16
brne appForwarderHandleClaimAddrRequest_ret
ldi r18, NETMSG_CMD_DENY_ADDRESS ; deny addr
rcall appForwarderSendAddrMsg ; (R16, R17, R18, R19, R20, R21, X, Y)
appForwarderHandleClaimAddrRequest_ret:
ret
; @end
; ---------------------------------------------------------------------------
; @routine appForwarderSendAddrMsg
;
; @param R18 command
; @param R19 address to send
; @param Y pointer to interface to send to
; @clobbers R16 (R17, R18, R19, R20, R21, X, Y)
appForwarderSendAddrMsg:
bigcall NET_Buffer_Alloc ; (R16, R17, X)
brcc appForwarderSendAddrMsg_end
push r16
adiw xh:xl, 1
bigcall NETMSG_Address_Write ; (R16, R17, R18, R19, R20, R21)
sbiw xh:xl, 1
pop r16
bigcall NET_Interface_AddOrReleaseOutMsg ; (R16, R17, R18, X)
appForwarderSendAddrMsg_end:
ret
; @end
; ---------------------------------------------------------------------------
; @routine appForwarderHandleRebootRequest
;
; Doesn't return if reboot msg is valid.
;
; @param X pointer to received message
appForwarderHandleRebootRequest:
rcall NETMSG_RebootRequestRead
brcc appForwarderHandleRebootRequest_end
; reboot
cli
bigjmp BOOTLOADER_ADDR
appForwarderHandleRebootRequest_end:
ret
; @end
; ---------------------------------------------------------------------------
; @routine appForwarderHandlePingRequest
;
; @param X pointer to received message
; @param Y pointer to source interface for the message
appForwarderHandlePingRequest:
ld r17, X
lds r16, (netInterfaceData+NET_IFACE_OFFS_ADDRESS)
cp r16, r17
breq appForwarderHandlePingRequest_forMe
cpi r17, 0xff
breq appForwarderHandlePingRequest_forMe
clc
rjmp appForwarderHandlePingRequest_end
appForwarderHandlePingRequest_forMe:
adiw xh:xl, NETMSG_OFFS_SRCADDR
ld r17, X
sbiw xh:xl, NETMSG_OFFS_SRCADDR
push r17
bigcall NET_Buffer_Alloc ; (R16, R17, X)
pop r17
brcc appForwarderHandlePingRequest_end ; jmp on error
push r16 ; buffer num
mov r16, r17 ; DEST addr
adiw xh:xl, 1
bigcall NETMSG_Pong_Write ; (R16, R17, R18, R19, R20, X)
sbiw xh:xl, 1
pop r16 ; buffer num
bigcall NET_Interface_AddOrReleaseOutMsg ; (R16, R17, R18, X)
appForwarderHandlePingRequest_end:
ret
; ---------------------------------------------------------------------------
; @routine appForwarderLetSysHandleMsg
;
; @param X pointer to msg to handle (point behind the buffer header!)
; @param Y pointer to source interface for the message
; @clobbers any, !X
appForwarderLetSysHandleMsg:
ld r16, X
cpi r16, 0xff
breq appForwarderLetSysHandleMsg_forMe
lds r17, netInterfaceData+NET_IFACE_OFFS_ADDRESS
cp r16, r17
brne appForwarderLetSysHandleMsg_end
appForwarderLetSysHandleMsg_forMe:
push xl
push xh
rcall onMessageReceived
pop xh
pop xl
push xl
push xh
rcall mainModulesOnPacketReceived
pop xh
pop xl
push xl
push xh
rcall mainAppsOnPacketReceived
pop xh
pop xl
appForwarderLetSysHandleMsg_end:
ret
; @end
; ---------------------------------------------------------------------------
; @routine appForwarderSendToOtherDev
; @param r16 buffer num
; @param r17 src interface num
appForwarderSendToOtherDev:
ldi yl, LOW(netInterfaceData)
ldi yh, HIGH(netInterfaceData)
ldd r18, Y+NET_IFACE_OFFS_IFACENUM
andi r18, 0x0f
cp r18, r17
breq appForwarderSendToAllDevsBut_check2
bigcall NET_Interface_AddOutgoingMsgNum ; (R17, R18, X)
rjmp appForwarderSendToOtherDev_ret
appForwarderSendToAllDevsBut_check2:
ldi yl, LOW(netInterfaceData2)
ldi yh, HIGH(netInterfaceData2)
ldd r18, Y+NET_IFACE_OFFS_IFACENUM
andi r18, 0x0f
cp r18, r17
breq appForwarderSendToOtherDev_ret
bigcall NET_Interface_AddOutgoingMsgNum ; (R17, R18, X)
appForwarderSendToOtherDev_ret:
ret
; @end
; ---------------------------------------------------------------------------
; @routine appForwarderGetDeviceByIfaceNum
;
; @param r16 interface number
; @return CFLAG set if interface found (cleared otherwise)
; @return Y pointer to interface with given number
; @clobbers r17
appForwarderGetDeviceByIfaceNum:
ldi yl, LOW(netInterfaceData)
ldi yh, HIGH(netInterfaceData)
ldd r17, Y+NET_IFACE_OFFS_IFACENUM
cp r16, r17
breq appForwarderGetDeviceByIfaceNum_secRet
ldi yl, LOW(netInterfaceData2)
ldi yh, HIGH(netInterfaceData2)
ldd r17, Y+NET_IFACE_OFFS_IFACENUM
cp r16, r17
breq appForwarderGetDeviceByIfaceNum_secRet
clc
rjmp appForwarderGetDeviceByIfaceNum_ret
appForwarderGetDeviceByIfaceNum_secRet:
sec
appForwarderGetDeviceByIfaceNum_ret:
ret
; @end