; *************************************************************************** ; 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