@@ -890,3 +890,108 @@ bool npdu_is_data_expecting_reply(
890890 request_pdu , request_pdu_len , & request_address , reply_pdu ,
891891 reply_pdu_len , & reply_address );
892892}
893+
894+ /**
895+ * @brief Process the NPDU portion of an I-Am-Router-To-Network message, which
896+ * contains a list of BACnet network numbers that the router is connected to.
897+ * @param snet [in] The source network number of the I-Am-Router-To
898+ * Network message, which is the network number of the router sending the
899+ * message.
900+ * @param src [in] The source address of the I-Am-Router-To-Network message,
901+ * which is the address of the router sending the message.
902+ * @param npdu [in] The buffer containing the NPDU portion of the
903+ * I-Am-Router-To-Network message, which contains the list of BACnet network
904+ * numbers that the router is connected to.
905+ * @param npdu_size [in] The size of the npdu buffer in bytes.
906+ * @param dnet_add [in] A callback function that will be called for each BACnet
907+ * network number (DNET)
908+ */
909+ void npdu_i_am_router_to_network_process (
910+ uint16_t snet ,
911+ const BACNET_ADDRESS * src ,
912+ const uint8_t * npdu ,
913+ uint16_t npdu_size ,
914+ npdu_dnet_add_callback_t dnet_add )
915+ {
916+ int len = 2 ;
917+ uint16_t dnet = 0 ;
918+ uint16_t npdu_offset = 0 ;
919+ uint16_t npdu_len = npdu_size ;
920+
921+ while (npdu_len >= len ) {
922+ len = decode_unsigned16 (& npdu [npdu_offset ], & dnet );
923+ if (dnet_add ) {
924+ dnet_add (snet , dnet , src );
925+ }
926+ npdu_len -= len ;
927+ npdu_offset += len ;
928+ }
929+ }
930+
931+ /**
932+ * @brief Process the NPDU portion of an Initialize-Routing-Table message, which
933+ * contains a list of BACnet network numbers (DNETs) and per-port information.
934+ * @param snet [in] The source network number of the Initialize-Routing-Table
935+ * message, which is the network number of the router sending the message.
936+ * @param src [in] The source address of the I-Have-Router-To-Network message,
937+ * which is the address of the router sending the message.
938+ * @param npdu [in] The buffer containing the NPDU portion of the
939+ * I-Have-Router-To-Network message, which contains the list of BACnet network
940+ * numbers that the router is connected to, along with port information.
941+ * @param npdu_size [in] The size of the npdu buffer in bytes.
942+ * @param dnet_add [in] Optional callback invoked for each decoded DNET value.
943+ * The callback receives the source network, decoded DNET, and source address.
944+ */
945+ void npdu_init_routing_table_process (
946+ uint16_t snet ,
947+ const BACNET_ADDRESS * src ,
948+ const uint8_t * npdu ,
949+ uint16_t npdu_size ,
950+ npdu_dnet_add_callback_t dnet_add )
951+ {
952+ int len = 2 ;
953+ uint16_t dnet = 0 ;
954+ uint16_t npdu_offset = 0 ;
955+ uint8_t port_id = 0 ;
956+ uint8_t port_info_len = 0 ;
957+ uint8_t net_count ;
958+ uint16_t npdu_len = npdu_size ;
959+
960+ if (npdu_len <= 1 ) {
961+ /* malformed message */
962+ return ;
963+ }
964+ net_count = npdu [npdu_offset ];
965+ npdu_offset += 1 ;
966+ npdu_len -= 1 ;
967+ if (net_count == 0 ) {
968+ /* no networks, nothing to do */
969+ return ;
970+ }
971+ /* DNET(2) + PortID(1) + PortInfoLen(1) = 4 bytes */
972+ while ((npdu_len >= 4 ) && (net_count -- )) {
973+ /* DNET */
974+ len = decode_unsigned16 (& npdu [npdu_offset ], & dnet );
975+ npdu_offset += len ;
976+ npdu_len -= len ;
977+ /* update routing table */
978+ if (dnet_add ) {
979+ dnet_add (snet , dnet , src );
980+ }
981+ /* skip port_id & port_info */
982+ port_id = npdu [npdu_offset ];
983+ npdu_offset += 1 ;
984+ npdu_len -= 1 ;
985+ port_info_len = npdu [npdu_offset ];
986+ npdu_offset += 1 ;
987+ npdu_len -= 1 ;
988+ if (npdu_len >= port_info_len ) {
989+ npdu_offset += port_info_len ;
990+ npdu_len -= port_info_len ;
991+ } else {
992+ /* malformed message */
993+ break ;
994+ }
995+ (void )port_id ;
996+ }
997+ }
0 commit comments