AllJoyn/Samples/BACnetAdapter/bacnet-stack-0.8.2/ports/arduino_uno/bip.c
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)
{
    int received_bytes = 0;
    uint16_t pdu_len = 0;       /* return value */
    uint8_t src_addr[] = { 0, 0, 0, 0 };
    uint16_t src_port = 0;
    uint16_t i = 0;
    int function = 0;

    /* Make sure the socket is open */
    if (BIP_Socket < 0)
        return 0;

    if (getRXReceivedSize_func(CW5100Class_new(), BIP_Socket)) {
        memcpy(&src_addr, &src->mac[0], 4);
        memcpy(&src_port, &src->mac[4], 2);
        received_bytes =
            (int) recvfrom_func(BIP_Socket, &pdu[0], max_pdu, src_addr,
            &src_port);
    }

    /* See if there is a problem */
    if (received_bytes < 0) {
        return 0;
    }

    /* no problem, just no bytes */
    if (received_bytes == 0)
        return 0;

    /* the signature of a BACnet/IP packet */
    if (pdu[0] != BVLL_TYPE_BACNET_IP)
        return 0;

    if (bvlc_for_non_bbmd(src_addr, &src_port, pdu, received_bytes) > 0) {
        /* Handled, usually with a NACK. */
#if PRINT_ENABLED
        fprintf(stderr, "BIP: BVLC discarded!\n");
#endif
        return 0;
    }

    function = bvlc_get_function_code();        /* aka, pdu[1] */
    if ((function == BVLC_ORIGINAL_UNICAST_NPDU) ||
        (function == BVLC_ORIGINAL_BROADCAST_NPDU)) {
        /* ignore messages from me */
        if ((convertBIP_Address2uint32(src_addr) ==
                convertBIP_Address2uint32(BIP_Address)) &&
            (src_port == BIP_Port)) {
            pdu_len = 0;
#if 0
            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], &src_addr, 4);
            memcpy(&src->mac[4], &src_port, 2);
#ifdef DEBUG
            fprintf(stderr, "BIP receive from %d.%d.%d.%d\n", src->mac[0],
                src->mac[1], src->mac[2], src->mac[3]);
#endif
            /* FIXME: check destination address */
            /* see if it is broadcast or for us */
            /* decode the length of the PDU - length is inclusive of BVLC */
            (void) decode_unsigned16(&pdu[2], &pdu_len);
            /* subtract off the BVLC header */
            pdu_len -= 4;
            if (pdu_len < max_pdu) {
#if 0
                fprintf(stderr, "BIP: NPDU[%hu]:", pdu_len);
#endif
                /* shift the buffer to return a valid PDU */
                for (i = 0; i < pdu_len; i++) {
                    pdu[i] = pdu[4 + i];
#if 0
                    fprintf(stderr, "%02X ", pdu[i]);
#endif
                }
#if 0
                fprintf(stderr, "\n");
#endif
            }
            /* ignore packets that are too large */
            /* clients should check my max-apdu first */
            else {
                pdu_len = 0;
#if PRINT_ENABLED
                fprintf(stderr, "BIP: PDU too large. Discarded!.\n");
#endif
            }
        }
    } else if (function == BVLC_FORWARDED_NPDU) {
        memcpy(&src_addr, &pdu[4], 4);
        memcpy(&src_port, &pdu[8], 2);
        if ((convertBIP_Address2uint32(src_addr) ==
                convertBIP_Address2uint32(BIP_Address)) &&
            (src_port == BIP_Port)) {
            /* ignore messages from me */
            pdu_len = 0;
        } else {
            /* data in src->mac[] is in network format */
            src->mac_len = 6;
            memcpy(&src->mac[0], &src_addr, 4);
            memcpy(&src->mac[4], &src_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 */
            (void) decode_unsigned16(&pdu[2], &pdu_len);
            /* subtract off the BVLC header */
            pdu_len -= 10;
            if (pdu_len < max_pdu) {
                /* shift the buffer to return a valid PDU */
                for (i = 0; i < pdu_len; i++) {
                    pdu[i] = pdu[4 + 6 + i];
                }
            } else {
                /* ignore packets that are too large */
                /* clients should check my max-apdu first */
                pdu_len = 0;
            }
        }
    }

    return pdu_len;
}
/** 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.
 */
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.
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,      
    uint8_t * pdu,      
    uint16_t max_pdu,   
    unsigned timeout)
{
    int received_bytes = 0;
    uint16_t pdu_len = 0;       
    uint8_t src_addr[] = { 0, 0, 0, 0 };
    uint16_t src_port = 0;
    uint16_t i = 0;
    int function = 0;
    if (BIP_Socket < 0)
        return 0;
    if (getRXReceivedSize_func(CW5100Class_new(), BIP_Socket)) {
        memcpy(&src_addr, &src->mac[0], 4);
        memcpy(&src_port, &src->mac[4], 2);
        received_bytes =
            (int) recvfrom_func(BIP_Socket, &pdu[0], max_pdu, src_addr,
            &src_port);
    }
    if (received_bytes < 0) {
        return 0;
    }
    if (received_bytes == 0)
        return 0;
    if (pdu[0] != BVLL_TYPE_BACNET_IP)
        return 0;
    if (bvlc_for_non_bbmd(src_addr, &src_port, pdu, received_bytes) > 0) {
#if PRINT_ENABLED
        fprintf(stderr, "BIP: BVLC discarded!\n");
#endif
        return 0;
    }
    function = bvlc_get_function_code();        
    if ((function == BVLC_ORIGINAL_UNICAST_NPDU) ||
        (function == BVLC_ORIGINAL_BROADCAST_NPDU)) {
        if ((convertBIP_Address2uint32(src_addr) ==
                convertBIP_Address2uint32(BIP_Address)) &&
            (src_port == BIP_Port)) {
            pdu_len = 0;
#if 0
            fprintf(stderr, "BIP: src is me. Discarded!\n");
#endif
        } else {
            src->mac_len = 6;
            memcpy(&src->mac[0], &src_addr, 4);
            memcpy(&src->mac[4], &src_port, 2);
#ifdef DEBUG
            fprintf(stderr, "BIP receive from %d.%d.%d.%d\n", src->mac[0],
                src->mac[1], src->mac[2], src->mac[3]);
#endif
            (void) decode_unsigned16(&pdu[2], &pdu_len);
            pdu_len -= 4;
            if (pdu_len < max_pdu) {
#if 0
                fprintf(stderr, "BIP: NPDU[%hu]:", pdu_len);
#endif
                for (i = 0; i < pdu_len; i++) {
                    pdu[i] = pdu[4 + i];
#if 0
                    fprintf(stderr, "%02X ", pdu[i]);
#endif
                }
#if 0
                fprintf(stderr, "\n");
#endif
            }
            else {
                pdu_len = 0;
#if PRINT_ENABLED
                fprintf(stderr, "BIP: PDU too large. Discarded!.\n");
#endif
            }
        }
    } else if (function == BVLC_FORWARDED_NPDU) {
        memcpy(&src_addr, &pdu[4], 4);
        memcpy(&src_port, &pdu[8], 2);
        if ((convertBIP_Address2uint32(src_addr) ==
                convertBIP_Address2uint32(BIP_Address)) &&
            (src_port == BIP_Port)) {
            pdu_len = 0;
        } else {
            src->mac_len = 6;
            memcpy(&src->mac[0], &src_addr, 4);
            memcpy(&src->mac[4], &src_port, 2);
            (void) decode_unsigned16(&pdu[2], &pdu_len);
            pdu_len -= 10;
            if (pdu_len < max_pdu) {
                for (i = 0; i < pdu_len; i++) {
                    pdu[i] = pdu[4 + 6 + i];
                }
            } else {
                pdu_len = 0;
            }
        }
    }
    return pdu_len;
}
uint16_t bip_receive ( BACNET_ADDRESS * src , uint8_t * pdu , uint16_t max_pdu , unsigned timeout ) { int received_bytes = 0 ; uint16_t pdu_len = 0 ; uint8_t src_addr [ ] = { 0 , 0 , 0 , 0 } ; uint16_t src_port = 0 ; uint16_t i = 0 ; int function = 0 ; if ( BIP_Socket < 0 ) return 0 ; if ( getRXReceivedSize_func ( CW5100Class_new ( ) , BIP_Socket ) ) { memcpy ( & src_addr , & src -> mac [ 0 ] , 4 ) ; memcpy ( & src_port , & src -> mac [ 4 ] , 2 ) ; received_bytes = ( int ) recvfrom_func ( BIP_Socket , & pdu [ 0 ] , max_pdu , src_addr , & src_port ) ; } if ( received_bytes < 0 ) { return 0 ; } if ( received_bytes == 0 ) return 0 ; if ( pdu [ 0 ] != BVLL_TYPE_BACNET_IP ) return 0 ; if ( bvlc_for_non_bbmd ( src_addr , & src_port , pdu , received_bytes ) > 0 ) { #if PRINT_ENABLED fprintf ( stderr , " \n " ) ; #endif return 0 ; } function = bvlc_get_function_code ( ) ; if ( ( function == BVLC_ORIGINAL_UNICAST_NPDU ) || ( function == BVLC_ORIGINAL_BROADCAST_NPDU ) ) { if ( ( convertBIP_Address2uint32 ( src_addr ) == convertBIP_Address2uint32 ( BIP_Address ) ) && ( src_port == BIP_Port ) ) { pdu_len = 0 ; #if 0 fprintf ( stderr , " \n " ) ; #endif } else { src -> mac_len = 6 ; memcpy ( & src -> mac [ 0 ] , & src_addr , 4 ) ; memcpy ( & src -> mac [ 4 ] , & src_port , 2 ) ; #ifdef DEBUG fprintf ( stderr , " \n " , src -> mac [ 0 ] , src -> mac [ 1 ] , src -> mac [ 2 ] , src -> mac [ 3 ] ) ; #endif ( void ) decode_unsigned16 ( & pdu [ 2 ] , & pdu_len ) ; pdu_len -= 4 ; if ( pdu_len < max_pdu ) { #if 0 fprintf ( stderr , " " , pdu_len ) ; #endif for ( i = 0 ; i < pdu_len ; i ++ ) { pdu [ i ] = pdu [ 4 + i ] ; #if 0 fprintf ( stderr , " " , pdu [ i ] ) ; #endif } #if 0 fprintf ( stderr , " \n " ) ; #endif } else { pdu_len = 0 ; #if PRINT_ENABLED fprintf ( stderr , " \n " ) ; #endif } } } else if ( function == BVLC_FORWARDED_NPDU ) { memcpy ( & src_addr , & pdu [ 4 ] , 4 ) ; memcpy ( & src_port , & pdu [ 8 ] , 2 ) ; if ( ( convertBIP_Address2uint32 ( src_addr ) == convertBIP_Address2uint32 ( BIP_Address ) ) && ( src_port == BIP_Port ) ) { pdu_len = 0 ; } else { src -> mac_len = 6 ; memcpy ( & src -> mac [ 0 ] , & src_addr , 4 ) ; memcpy ( & src -> mac [ 4 ] , & src_port , 2 ) ; ( void ) decode_unsigned16 ( & pdu [ 2 ] , & pdu_len ) ; pdu_len -= 10 ; if ( pdu_len < max_pdu ) { for ( i = 0 ; i < pdu_len ; i ++ ) { pdu [ i ] = pdu [ 4 + 6 + i ] ; } } else { pdu_len = 0 ; } } } return pdu_len ; }
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.
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 .
/* source address */ /* PDU data */ /* amount of space available in the PDU  */ /* return value */ /* Make sure the socket is open */ /* See if there is a problem */ /* no problem, just no bytes */ /* the signature of a BACnet/IP packet */ /* Handled, usually with a NACK. */ /* aka, pdu[1] */ /* ignore messages from me */ /* data in src->mac[] is in network format */ /* FIXME: check destination address */ /* see if it is broadcast or for us */ /* decode the length of the PDU - length is inclusive of BVLC */ /* subtract off the BVLC header */ /* shift the buffer to return a valid PDU */ /* ignore packets that are too large */ /* clients should check my max-apdu first */ /* ignore messages from me */ /* data in src->mac[] is in network format */ /* FIXME: check destination address */ /* see if it is broadcast or for us */ /* decode the length of the PDU - length is inclusive of BVLC */ /* subtract off the BVLC header */ /* shift the buffer to return a valid PDU */ /* ignore packets that are too large */ /* clients should check my max-apdu first */