Ejemplo n.º 1
0
static void My_NPDU_Handler(
    BACNET_ADDRESS * src,       /* source address */
    uint8_t * pdu,      /* PDU data */
    uint16_t pdu_len)
{       /* length PDU  */
    int apdu_offset = 0;
    BACNET_ADDRESS dest = { 0 };
    BACNET_NPDU_DATA npdu_data = { 0 };

    apdu_offset = npdu_decode(&pdu[0], &dest, src, &npdu_data);
    if (npdu_data.network_layer_message) {
        if (apdu_offset <= pdu_len) {
            My_Router_Handler(src, &npdu_data, &pdu[apdu_offset],
                (uint16_t) (pdu_len - apdu_offset));
        }
    } else if ((apdu_offset > 0) && (apdu_offset <= pdu_len)) {
        if ((npdu_data.protocol_version == BACNET_PROTOCOL_VERSION) &&
            ((dest.net == 0) || (dest.net == BACNET_BROADCAST_NETWORK))) {
            /* only handle the version that we know how to handle */
            /* and we are not a router, so ignore messages with
               routing information cause they are not for us */
            apdu_handler(src, &pdu[apdu_offset],
                (uint16_t) (pdu_len - apdu_offset));
        } else {
            if (dest.net) {
                debug_printf("NPDU: DNET=%d.  Discarded!\n", dest.net);
            } else {
                debug_printf("NPDU: BACnet Protocol Version=%d.  Discarded!\n",
                    npdu_data.protocol_version);
            }
        }
    }

    return;
}
Ejemplo n.º 2
0
/** Handler for the NPDU portion of a received packet.
 *  Aside from error-checking, if the NPDU doesn't contain routing info,
 *  this handler doesn't do much besides stepping over the NPDU header
 *  and passing the remaining bytes to the apdu_handler.
 *  @note The routing (except src) and NCPI information, including
 *  npdu_data->data_expecting_reply, are discarded.
 * @see routing_npdu_handler
 *
 * @ingroup MISCHNDLR
 *
 * @param src  [out] Returned with routing source information if the NPDU
 *                   has any and if this points to non-null storage for it.
 *                   If src->net and src->len are 0 on return, there is no
 *                   routing source information.
 *                   This src describes the original source of the message when
 *                   it had to be routed to reach this BACnet Device, and this
 *                   is passed down into the apdu_handler; however, I don't
 *                   think this project's code has any use for the src info
 *                   on return from this handler, since the response has
 *                   already been sent via the apdu_handler.
 *  @param pdu [in]  Buffer containing the NPDU and APDU of the received packet.
 *  @param pdu_len [in] The size of the received message in the pdu[] buffer.
 */
void npdu_handler(
    PORT_SUPPORT *portParams,
    BACNET_ADDRESS * src,       /* source address */
    uint8_t * pdu,      /* PDU data */
    uint16_t pdu_len)
{       /* length PDU  */
    int apdu_offset = 0;
    BACNET_ADDRESS dest = { 0 };
    BACNET_NPDU_DATA npdu_data = { 0 };

    /* only handle the version that we know how to handle */
    if (pdu[0] == BACNET_PROTOCOL_VERSION) {
        apdu_offset = npdu_decode(&pdu[0], &dest, src, &npdu_data);
        if (npdu_data.network_layer_message) {
            /*FIXME: network layer message received!  Handle it! */
#if PRINT_ENABLED
            fprintf(stderr, "NPDU: Network Layer Message discarded!\n");
#endif
        } else if ((apdu_offset > 0) && (apdu_offset <= pdu_len)) {
            if ((dest.net == 0) || (dest.net == BACNET_BROADCAST_NETWORK)) {
                /* only handle the version that we know how to handle */
                /* and we are not a router, so ignore messages with
                   routing information cause they are not for us */
                if ((dest.net == BACNET_BROADCAST_NETWORK) &&
                    ((pdu[apdu_offset] & 0xF0) ==
                        PDU_TYPE_CONFIRMED_SERVICE_REQUEST)) {
                    /* hack for 5.4.5.1 - IDLE */
                    /* ConfirmedBroadcastReceived */
                    /* then enter IDLE - ignore the PDU */
                } else {
                    apdu_handler(portParams, src, &pdu[apdu_offset],
                        (uint16_t) (pdu_len - apdu_offset));
                }
            } else {
#if PRINT_ENABLED
                printf("NPDU: DNET=%u.  Discarded!\n", (unsigned) dest.net);
#endif
            }
        }
    } else {
#if PRINT_ENABLED
        printf("NPDU: BACnet Protocol Version=%u.  Discarded!\n",
            (unsigned) pdu[0]);
#endif
    }

    return;
}
Ejemplo n.º 3
0
/** An APDU pre-handler that makes sure that the subsequent APDU handler call 
 * operates on the right Device Object(s), as addressed by the destination 
 * (routing) information.
 * 
 * @note Even when the destination is "routed" to our virtual BACnet network,
 * the src information does not need to change to reflect that (as it normally
 * would for a routed message) because the reply will be sent from the level 
 * of the gateway Device.
 * 
 * @param src [in] The BACNET_ADDRESS of the message's source.
 * @param dest [in] The BACNET_ADDRESS of the message's destination.
 * @param DNET_list [in] List of our reachable downstream BACnet Network numbers.
 * 					 Normally just one valid entry; terminated with a -1 value.
 * @param apdu [in] The apdu portion of the request, to be processed.
 * @param apdu_len [in] The total (remaining) length of the apdu.
 */
static void routed_apdu_handler(
    BACNET_ADDRESS * src,
    BACNET_ADDRESS * dest,
    int *DNET_list,
    uint8_t * apdu,
    uint16_t apdu_len)
{
    int cursor = 0;     /* Starting hint */
    bool bGotOne = false;

    if (!Routed_Device_Is_Valid_Network(dest->net, DNET_list)) {
        /* We don't know how to reach this one.
         * The protocol doesn't specifically state this, but if this message
         * was broadcast to us, we should assume "someone else" is handling
         * it and not get involved (ie, send a Reject-Message). 
         * Since we can't reach other routers that src couldn't already reach, 
         * we don't try the standard path of asking Who-Is-Router-to-Network. */
#if defined(BACDL_BIP)
        /* If wasn't unicast to us, must have been one of the bcast types.
         * Drop it. */
        if (bvlc_get_function_code() != BVLC_ORIGINAL_UNICAST_NPDU)
            return;
#endif
        /* Upper level handlers knew that this was sent as a bcast,
         * but our only other way to guess at that here is if the dest->adr
         * is absent, then we know this is some sort of bcast.
         */
        if (dest->len > 0) {
            Send_Reject_Message_To_Network(src, NETWORK_REJECT_NO_ROUTE,
                dest->net);
        }       /* else, silently drop it */
        return;
    }

    while (Routed_Device_GetNext(dest, DNET_list, &cursor)) {
        apdu_handler(src, apdu, apdu_len);
        bGotOne = true;
        if (cursor < 0) /* If no more matches, */
            break;      /* We don't need to keep looking */
    }
    if (!bGotOne) {
        /* Just silently drop this packet. */
    }
}
Ejemplo n.º 4
0
/** Handler for the NPDU portion of a received packet.
 *  Aside from error-checking, if the NPDU doesn't contain routing info,
 *  this handler doesn't do much besides stepping over the NPDU header
 *  and passing the remaining bytes to the apdu_handler.
 *  @note The routing (except src) and NCPI information, including 
 *  npdu_data->data_expecting_reply, are discarded.
 * @see routing_npdu_handler
 *  
 * @ingroup MISCHNDLR
 *  
 * @param src  [out] Returned with routing source information if the NPDU 
 *                   has any and if this points to non-null storage for it. 
 *                   If src->net and src->len are 0 on return, there is no
 *                   routing source information.
 *                   This src describes the original source of the message when
 *                   it had to be routed to reach this BACnet Device, and this
 *                   is passed down into the apdu_handler; however, I don't 
 *                   think this project's code has any use for the src info  
 *                   on return from this handler, since the response has 
 *                   already been sent via the apdu_handler.
 *  @param pdu [in]  Buffer containing the NPDU and APDU of the received packet.
 *  @param pdu_len [in] The size of the received message in the pdu[] buffer.
 */
void npdu_handler(
    BACNET_ADDRESS * src,       /* source address */
    uint8_t * pdu,      /* PDU data */
    uint16_t pdu_len)
{       /* length PDU  */
    int apdu_offset = 0;
    BACNET_ADDRESS dest = { 0 };
    BACNET_NPDU_DATA npdu_data = { 0 };

    /* only handle the version that we know how to handle */
    if (pdu[0] == BACNET_PROTOCOL_VERSION) {
        apdu_offset = npdu_decode(&pdu[0], &dest, src, &npdu_data);
        if (npdu_data.network_layer_message) {
            /*FIXME: network layer message received!  Handle it! */
#ifdef PRINT_ENABLE
            fprintf(stderr, "NPDU: Network Layer Message discarded!\n");
#endif
        } else if ((apdu_offset > 0) && (apdu_offset <= pdu_len)) {
            if ((dest.net == 0) || (dest.net == BACNET_BROADCAST_NETWORK)) {
                /* only handle the version that we know how to handle */
                /* and we are not a router, so ignore messages with
                   routing information cause they are not for us */
                apdu_handler(src, &pdu[apdu_offset],
                    (uint16_t) (pdu_len - apdu_offset));
            } else {
#ifdef PRINT_ENABLE
                fprintf(stderr, "NPDU: DNET=%u.  Discarded!\n", (unsigned) dest.net);
#endif
            }
        }
    } else {
#ifdef PRINT_ENABLE
        fprintf(stderr, "NPDU: BACnet Protocol Version=%u.  Discarded!\n",
            (unsigned) pdu[0]);
#endif
    }

    return;
}