diff --git a/bacnet-stack/src/bip.c b/bacnet-stack/src/bip.c index a973c292..d4cb52d7 100644 --- a/bacnet-stack/src/bip.c +++ b/bacnet-stack/src/bip.c @@ -209,14 +209,23 @@ int bip_send_pdu( return bytes_sent; } -/* receives a BACnet/IP packet */ -/* returns the number of octets in the PDU, or zero on failure */ +/** Implementation of the receive() function for BACnet/IP; receives one + * packet, verifies its BVLC header, and removes the BVLC header from + * the PDU data before returning. + * + * @param src [out] Source of the packet - who should receive any response. + * @param pdu [out] A buffer to hold the PDU portion of the received packet, + * after the BVLC portion has been stripped off. + * @param max_pdu [in] Size of the pdu[] buffer. + * @param timeout [in] The number of milliseconds to wait for a packet. + * @return The number of octets (remaining) in the PDU, or zero on failure. + */ uint16_t bip_receive( BACNET_ADDRESS * src, /* source address */ uint8_t * pdu, /* PDU data */ uint16_t max_pdu, /* amount of space available in the PDU */ unsigned timeout) -{ /* number of milliseconds to wait for a packet */ +{ int received_bytes = 0; uint16_t pdu_len = 0; /* return value */ fd_set read_fds; @@ -274,10 +283,20 @@ uint16_t bip_receive( fprintf(stderr, "BIP: src is me. Discarded!\n"); #endif } else { - /* data in src->mac[] is in network format */ - src->mac_len = 6; - memcpy(&src->mac[0], &sin.sin_addr.s_addr, 4); - memcpy(&src->mac[4], &sin.sin_port, 2); + /* If this was an Original_Broadcast, ensure that + * the response gets bcast back by this: + */ + if (pdu[1] == BVLC_ORIGINAL_BROADCAST_NPDU) { + src->net = BACNET_BROADCAST_NETWORK; + src->mac_len = 0; + } else { + src->net = 0; + /* data in src->mac[] is in network format */ + src->mac_len = 6; + memcpy(&src->mac[0], &sin.sin_addr.s_addr, 4); + memcpy(&src->mac[4], &sin.sin_port, 2); + } + /* FIXME: check destination address */ /* see if it is broadcast or for us */ /* decode the length of the PDU - length is inclusive of BVLC */ diff --git a/bacnet-stack/src/npdu.c b/bacnet-stack/src/npdu.c index 6de5aca0..515a08c2 100644 --- a/bacnet-stack/src/npdu.c +++ b/bacnet-stack/src/npdu.c @@ -409,7 +409,12 @@ int npdu_decode( } } } else if (src) { - src->net = 0; + /* Clear the net number, with one exception: if the receive() + * function set it to BACNET_BROADCAST_NETWORK, (eg, for + * BVLC_ORIGINAL_BROADCAST_NPDU) then don't stomp on that. + */ + if ( src->net != BACNET_BROADCAST_NETWORK ) + src->net = 0; src->len = 0; for (i = 0; i < MAX_MAC_LEN; i++) { src->adr[i] = 0;