示例#1
0
/** Handler for Who-Has requests in the virtual routing setup,
 * with broadcast I-Have response.
 * Will respond if the device Object ID matches, and we have
 * the Object or Object Name requested.
 *
 * @ingroup DMDOB
 * @param service_request [in] The received message to be handled.
 * @param service_len [in] Length of the service_request message.
 * @param src [in] The BACNET_ADDRESS of the message's source (ignored).
 */
void handler_who_has_for_routing(
    uint8_t * service_request,
    uint16_t service_len,
    BACNET_ADDRESS * src)
{
    int len = 0;
    BACNET_WHO_HAS_DATA data;
    int32_t dev_instance;
    int cursor = 0;     /* Starting hint */
    int my_list[2] = { 0, -1 }; /* Not really used, so dummy values */
    BACNET_ADDRESS bcast_net;

    (void) src;
    len = whohas_decode_service_request(service_request, service_len, &data);
    if (len > 0) {
        /* Go through all devices, starting with the root gateway Device */
        memset(&bcast_net, 0, sizeof(BACNET_ADDRESS));
        bcast_net.net = BACNET_BROADCAST_NETWORK;       /* That's all we have to set */
        while (Routed_Device_GetNext(&bcast_net, my_list, &cursor)) {
            dev_instance = Device_Object_Instance_Number();
            if ((data.low_limit == -1) || (data.high_limit == -1) ||
                ((dev_instance >= data.low_limit) &&
                    (dev_instance <= data.high_limit)))
                match_name_or_object(&data);
        }
    }
}
示例#2
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. */
    }
}