Exemple #1
0
void Send_TimeSyncUTC(
    BACNET_DATE * bdate,
    BACNET_TIME * btime)
{
    int pdu_len = 0;
    BACNET_ADDRESS dest;
    int bytes_sent = 0;
    BACNET_NPDU_DATA npdu_data;

    if (!dcc_communication_enabled())
        return;

    /* we could use unicast or broadcast */
    datalink_get_broadcast_address(&dest);
    /* encode the NPDU portion of the packet */
    npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL);
    pdu_len =
        npdu_encode_pdu(&Handler_Transmit_Buffer[0], &dest, NULL, &npdu_data);
    /* encode the APDU portion of the packet */
    pdu_len =
        timesync_utc_encode_apdu(&Handler_Transmit_Buffer[0], bdate, btime);
    bytes_sent =
        datalink_send_pdu(&dest, &npdu_data, &Handler_Transmit_Buffer[0],
        pdu_len);
#if PRINT_ENABLED
    if (bytes_sent <= 0)
        fprintf(stderr,
            "Failed to Send UTC-Time-Synchronization Request (%s)!\n",
            strerror(errno));
#endif
}
Exemple #2
0
/** Send a local Who-Is request for a specific device, a range, or any device.
 * If low_limit and high_limit both are -1, then the range is unlimited.
 * If low_limit and high_limit have the same non-negative value, then only
 * that device will respond.
 * Otherwise, low_limit must be less than high_limit.
 * @param low_limit [in] Device Instance Low Range, 0 - 4,194,303 or -1
 * @param high_limit [in] Device Instance High Range, 0 - 4,194,303 or -1
 */
void Send_WhoIs_Local(
    int32_t low_limit,
    int32_t high_limit)
{
    BACNET_ADDRESS dest;
    char temp[6];
    int loop;

    if (!dcc_communication_enabled())
        return;

    /* Who-Is is a global broadcast */
    datalink_get_broadcast_address(&dest);
    /* encode the NPDU portion of the packet */

    /* I added this to make it a local broadcast */
    dest.net = 0;

    /* Not sure why this happens but values are backwards so they need to be reversed */

    temp[0] = dest.mac[3];
    temp[1] = dest.mac[2];
    temp[2] = dest.mac[1];
    temp[3] = dest.mac[0];
    temp[4] = dest.mac[5];
    temp[5] = dest.mac[4];


    for (loop = 0; loop < 6; loop++) {
        dest.mac[loop] = temp[loop];
    }

    Send_WhoIs_To_Network(&dest, low_limit, high_limit);
}
Exemple #3
0
void Send_UnconfirmedPrivateTransfer(
    BACNET_ADDRESS * dest,
    BACNET_PRIVATE_TRANSFER_DATA * private_data)
{
    int len = 0;
    int pdu_len = 0;
    int bytes_sent = 0;
    BACNET_NPDU_DATA npdu_data;
    BACNET_ADDRESS my_address;
    if (!dcc_communication_enabled())
        return;
    datalink_get_my_address(&my_address);
    /* encode the NPDU portion of the packet */
    npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL);
    pdu_len =
        npdu_encode_pdu(&Handler_Transmit_Buffer[0], dest, &my_address,
        &npdu_data);
    /* encode the APDU portion of the packet */
    len =
        ptransfer_ack_encode_apdu(&Handler_Transmit_Buffer[pdu_len],invoke_id,
        private_data);
    pdu_len += len;
    bytes_sent =
        datalink_send_pdu(dest, &npdu_data, &Handler_Transmit_Buffer[0],
        pdu_len);
#if PRINT_ENABLED
    if (bytes_sent <= 0)
        fprintf(stderr,
            "Failed to Send UnconfirmedPrivateTransfer Request (%s)!\n",
            strerror(errno));
#endif
}
Exemple #4
0
/**
 * Sends a TimeSync message to a specific destination
 *
 * @param dest - #BACNET_ADDRESS - the specific destination
 * @param bdate - #BACNET_DATE
 * @param btime - #BACNET_TIME
 */
void Send_TimeSync_Remote(
    BACNET_ADDRESS * dest,
    BACNET_DATE * bdate,
    BACNET_TIME * btime)
{
    int len = 0;
    int pdu_len = 0;
    int bytes_sent = 0;
    BACNET_NPDU_DATA npdu_data;
    BACNET_ADDRESS my_address;

    if (!dcc_communication_enabled())
        return;

    datalink_get_my_address(&my_address);
    /* encode the NPDU portion of the packet */
    npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL);
    pdu_len =
        npdu_encode_pdu(&Handler_Transmit_Buffer[0], dest, &my_address,
        &npdu_data);
    /* encode the APDU portion of the packet */
    len =
        timesync_encode_apdu(&Handler_Transmit_Buffer[pdu_len], bdate, btime);
    pdu_len += len;
    /* send it out the datalink */
    bytes_sent =
        datalink_send_pdu(dest, &npdu_data, &Handler_Transmit_Buffer[0],
        pdu_len);
#if PRINT_ENABLED
    if (bytes_sent <= 0)
        fprintf(stderr, "Failed to Send Time-Synchronization Request (%s)!\n",
            strerror(errno));
#endif
}
Exemple #5
0
/** Send a Who-Is request to a remote network for a specific device, a range,
 * or any device.
 * @ingroup DMDDB
 * If low_limit and high_limit both are -1, then the range is unlimited.
 * If low_limit and high_limit have the same non-negative value, then only
 * that device will respond.
 * Otherwise, low_limit must be less than high_limit.
 * @param target_address [in] BACnet address of target router
 * @param low_limit [in] Device Instance Low Range, 0 - 4,194,303 or -1
 * @param high_limit [in] Device Instance High Range, 0 - 4,194,303 or -1
 */
void Send_WhoIs_Remote(
    BACNET_ADDRESS * target_address,
    int32_t low_limit,
    int32_t high_limit)
{
    if (!dcc_communication_enabled())
        return;

    Send_WhoIs_To_Network(target_address, low_limit, high_limit);
}
Exemple #6
0
/** Send a global Who-Is request for a specific device, a range, or any device.
 * If low_limit and high_limit both are -1, then the range is unlimited.
 * If low_limit and high_limit have the same non-negative value, then only
 * that device will respond.
 * Otherwise, low_limit must be less than high_limit.
 * @param low_limit [in] Device Instance Low Range, 0 - 4,194,303 or -1
 * @param high_limit [in] Device Instance High Range, 0 - 4,194,303 or -1
 */
void Send_WhoIs_Global(
    int32_t low_limit,
    int32_t high_limit)
{
    BACNET_ADDRESS dest;

    if (!dcc_communication_enabled())
        return;

    /* Who-Is is a global broadcast */
    datalink_get_broadcast_address(&dest);

    Send_WhoIs_To_Network(&dest, low_limit, high_limit);
}
int Send_ConfirmedPrivateTransfer(
	BACNET_ADDRESS * dest,
	BACNET_PRIVATE_TRANSFER_DATA * private_data)
{
	int len = 0;
	int pdu_len = 0;
	int bytes_sent = 0;
	BACNET_NPDU_DATA npdu_data;
	BACNET_ADDRESS my_address;
	int invoke_id = 0;
	if (!dcc_communication_enabled())
		return -1;

	datalink_get_my_address(&my_address);
	/* encode the NPDU portion of the packet */
	// npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL);	//Fance
	npdu_encode_npdu_data(&npdu_data, true, MESSAGE_PRIORITY_NORMAL);
	pdu_len =
		npdu_encode_pdu(&Handler_Transmit_Buffer[0], dest, &my_address,
		&npdu_data);

	/* encode the APDU portion of the packet */

	 invoke_id = tsm_next_free_invokeID();
	 if(invoke_id==0)//这里是当没有可用的调用ID的时候将所有ID都清零;变为可用;
		 tsm_free_all_invoke_id();
	len =
		ptransfer_encode_apdu(&Handler_Transmit_Buffer[pdu_len],invoke_id,private_data);	//这里的还需要完善 Invoke ID
	// uptransfer_encode_apdu(&Handler_Transmit_Buffer[pdu_len],		//Fance
	// private_data);
	pdu_len += len;
	bytes_sent =
		datalink_send_pdu(dest, &npdu_data, &Handler_Transmit_Buffer[0],
		pdu_len);
#if PRINT_ENABLED
	if (bytes_sent <= 0)
		fprintf(stderr,
		"Failed to Send UnconfirmedPrivateTransfer Request (%s)!\n",
		strerror(errno));
#endif
	if(bytes_sent>0)
		return invoke_id;
	else
		return -2;
}
Exemple #8
0
/** Send a Who-Has request for a device which has a specific Object type and ID.
 * @ingroup DMDOB
 * If low_limit and high_limit both are -1, then the device ID range is unlimited.
 * If low_limit and high_limit have the same non-negative value, then only
 * that device will respond.
 * Otherwise, low_limit must be less than high_limit for a range.
 * @param low_limit [in] Device Instance Low Range, 0 - 4,194,303 or -1
 * @param high_limit [in] Device Instance High Range, 0 - 4,194,303 or -1
 * @param object_type [in] The BACNET_OBJECT_TYPE of the desired Object.
 * @param object_instance [in] The ID of the desired Object.
 */
void Send_WhoHas_Object(
    int32_t low_limit,
    int32_t high_limit,
    BACNET_OBJECT_TYPE object_type,
    uint32_t object_instance)
{
    int len = 0;
    int pdu_len = 0;
    BACNET_ADDRESS dest;
    int bytes_sent = 0;
    BACNET_WHO_HAS_DATA data;
    BACNET_NPDU_DATA npdu_data;
    BACNET_ADDRESS my_address;

    /* if we are forbidden to send, don't send! */
    if (!dcc_communication_enabled())
        return;
    /* Who-Has is a global broadcast */
    datalink_get_broadcast_address(&dest);
    datalink_get_my_address(&my_address);
    /* encode the NPDU portion of the packet */
    npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL);
    pdu_len =
        npdu_encode_pdu(&Handler_Transmit_Buffer[0], &dest, &my_address,
        &npdu_data);

    /* encode the APDU portion of the packet */
    data.low_limit = low_limit;
    data.high_limit = high_limit;
    data.is_object_name = false;
    data.object.identifier.type = object_type;
    data.object.identifier.instance = object_instance;
    len = whohas_encode_apdu(&Handler_Transmit_Buffer[pdu_len], &data);
    pdu_len += len;
    bytes_sent =
        datalink_send_pdu(&dest, &npdu_data, &Handler_Transmit_Buffer[0],
        pdu_len);
#if PRINT_ENABLED
    if (bytes_sent <= 0)
        fprintf(stderr, "Failed to Send Who-Has Request (%s)!\n",
            strerror(errno));
#endif
}
Exemple #9
0
/* find a specific device, or use -1 for limit if you want unlimited */
void Send_I_Have(
    uint32_t device_id,
    BACNET_OBJECT_TYPE object_type,
    uint32_t object_instance,
    char *object_name)
{
    int len = 0;
    int pdu_len = 0;
    BACNET_ADDRESS dest;
    int bytes_sent = 0;
    BACNET_I_HAVE_DATA data;
    BACNET_NPDU_DATA npdu_data;

    /* if we are forbidden to send, don't send! */
    if (!dcc_communication_enabled())
        return;
    /* Who-Has is a global broadcast */
    datalink_get_broadcast_address(&dest);
    /* encode the NPDU portion of the packet */
    npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL);
    pdu_len =
        npdu_encode_pdu(&Handler_Transmit_Buffer[0], &dest, NULL, &npdu_data);
    /* encode the APDU portion of the packet */
    data.device_id.type = OBJECT_DEVICE;
    data.device_id.instance = device_id;
    data.object_id.type = object_type;
    data.object_id.instance = object_instance;
    characterstring_init_ansi(&data.object_name, object_name);
    len = ihave_encode_apdu(&Handler_Transmit_Buffer[pdu_len], &data);
    pdu_len += len;
    /* send the data */
    bytes_sent =
        datalink_send_pdu(&dest, &npdu_data, &Handler_Transmit_Buffer[0],
        pdu_len);
#if PRINT_ENABLED
    if (bytes_sent <= 0)
        fprintf(stderr, "Failed to Send I-Have Reply (%s)!\n",
            strerror(errno));
#endif
}
Exemple #10
0
/* returns the invoke id, 0=unsuccessful */
uint8_t Send_CEvent_Notify(
    uint32_t device_id,
    BACNET_EVENT_NOTIFICATION_DATA * data)
{
    int len = 0;
    int pdu_len = 0;
    int bytes_sent = 0;
    BACNET_NPDU_DATA npdu_data;
    BACNET_ADDRESS dest;
    BACNET_ADDRESS my_address;
    unsigned max_apdu = 0;
    bool status = false;
    uint8_t invoke_id = 0;

    if (!dcc_communication_enabled())
        return 0;

    /* is the device bound? */
    status = address_get_by_device(device_id, &max_apdu, &dest);
    /* is there a tsm available? */
    if (status)
        invoke_id = tsm_next_free_invokeID();
    if (invoke_id) {
        /* encode the NPDU portion of the packet */
        datalink_get_my_address(&my_address);
        npdu_encode_npdu_data(&npdu_data, true, MESSAGE_PRIORITY_NORMAL);
        pdu_len =
            npdu_encode_pdu(&Handler_Transmit_Buffer[0], &dest, &my_address,
            &npdu_data);
        /* encode the APDU portion of the packet */
        len =
            cevent_notify_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
            invoke_id, data);
        pdu_len += len;
        /* will it fit in the sender?
           note: if there is a bottleneck router in between
           us and the destination, we won't know unless
           we have a way to check for that and update the
           max_apdu in the address binding table. */
        if ((unsigned) pdu_len < max_apdu) {
            tsm_set_confirmed_unsegmented_transaction(invoke_id, &dest,
                &npdu_data, &Handler_Transmit_Buffer[0], (uint16_t) pdu_len);
            bytes_sent =
                datalink_send_pdu(&dest, &npdu_data,
                &Handler_Transmit_Buffer[0], pdu_len);
#if PRINT_ENABLED
            if (bytes_sent <= 0) {
                fprintf(stderr,
                    "Failed to Send ConfirmedEventNotification Request (%s)!\n",
                    strerror(errno));
            }
#endif
        } else {
            tsm_free_invoke_id(invoke_id);
            invoke_id = 0;
#if PRINT_ENABLED
            fprintf(stderr,
                "Failed to Send ConfirmedEventNotification Request "
                "(exceeds destination maximum APDU)!\n");
#endif
        }
    }

    return invoke_id;
}
Exemple #11
0
int BacnetTimeSync(
    int deviceInstanceNumber,
    int year,
    int month,
    int day,
    int hour,
    int minute,
    int second,
    int isUTC,
    int UTCOffset)
{
    BACNET_DATE bdate;
    BACNET_TIME btime;
    struct tm my_time;
    time_t aTime;
    struct tm *newTime;

    my_time.tm_sec = second;
    my_time.tm_min = minute;
    my_time.tm_hour = hour;
    my_time.tm_mday = day;
    my_time.tm_mon = month - 1;
    my_time.tm_year = year - 1900;
    my_time.tm_wday = 0;        /* does not matter */
    my_time.tm_yday = 0;        /* does not matter */
    my_time.tm_isdst = 0;       /* does not matter */

    aTime = mktime(&my_time);
    newTime = localtime(&aTime);

    bdate.year = newTime->tm_year;
    bdate.month = newTime->tm_mon + 1;
    bdate.day = newTime->tm_mday;
    bdate.wday = newTime->tm_wday ? newTime->tm_wday : 7;
    btime.hour = newTime->tm_hour;
    btime.min = newTime->tm_min;
    btime.sec = newTime->tm_sec;
    btime.hundredths = 0;

    int len = 0;
    int pdu_len = 0;
    int bytes_sent = 0;
    BACNET_NPDU_DATA npdu_data;
    BACNET_ADDRESS my_address;
    uint8_t Handler_Transmit_Buffer[MAX_PDU] = { 0 };

    /* Loop for eary exit */
    do {
        if (!dcc_communication_enabled()) {
            LogError("DCC communicaiton is not enabled");
            break;
        }

        /* encode the NPDU portion of the packet */
        npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL);
        datalink_get_my_address(&my_address);
        pdu_len =
            npdu_encode_pdu(&Handler_Transmit_Buffer[0], &Target_Address,
            &my_address, &npdu_data);

        /* encode the APDU portion of the packet */
        len =
            timesync_encode_apdu(&Handler_Transmit_Buffer[pdu_len], &bdate,
            &btime);
        pdu_len += len;

        /* send it out the datalink */
        bytes_sent =
            datalink_send_pdu(&Target_Address, &npdu_data,
            &Handler_Transmit_Buffer[0], pdu_len);
        if (bytes_sent <= 0) {
            char errorMsg[64];
            sprintf(errorMsg,
                "Failed to Send Time-Synchronization Request (%s)!",
                strerror(errno));
            LogError(errorMsg);
            break;
        }

        Wait_For_Answer_Or_Timeout(100, waitAnswer);
    } while (false);

    int isFailure = Error_Detected;
    Error_Detected = 0;
    return isFailure;
}
Exemple #12
0
static bool cov_send_request(
    BACNET_COV_SUBSCRIPTION * cov_subscription,
    BACNET_PROPERTY_VALUE * value_list)
{
    int len = 0;
    int pdu_len = 0;
    BACNET_NPDU_DATA npdu_data;
    BACNET_ADDRESS my_address;
    int bytes_sent = 0;
    uint8_t invoke_id = 0;
    bool status = false;        /* return value */
    BACNET_COV_DATA cov_data;

    if (!dcc_communication_enabled()) {
        return status;
    }
#if PRINT_ENABLED
    fprintf(stderr, "COVnotification: requested\n");
#endif
    datalink_get_my_address(&my_address);
    npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL);
    pdu_len =
        npdu_encode_pdu(&Handler_Transmit_Buffer[0], &cov_subscription->dest,
        &my_address, &npdu_data);
    /* load the COV data structure for outgoing message */
    cov_data.subscriberProcessIdentifier =
        cov_subscription->subscriberProcessIdentifier;
    cov_data.initiatingDeviceIdentifier = Device_Object_Instance_Number();
    cov_data.monitoredObjectIdentifier.type =
        cov_subscription->monitoredObjectIdentifier.type;
    cov_data.monitoredObjectIdentifier.instance =
        cov_subscription->monitoredObjectIdentifier.instance;
    cov_data.timeRemaining = cov_subscription->lifetime;
    cov_data.listOfValues = value_list;
    if (cov_subscription->flag.issueConfirmedNotifications) {
        invoke_id = tsm_next_free_invokeID();
        if (invoke_id) {
            cov_subscription->invokeID = invoke_id;
            len =
                ccov_notify_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
                invoke_id, &cov_data);
        } else {
            goto COV_FAILED;
        }
    } else {
        len =
            ucov_notify_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
            &cov_data);
    }
    pdu_len += len;
    if (cov_subscription->flag.issueConfirmedNotifications) {
        tsm_set_confirmed_unsegmented_transaction(invoke_id,
            &cov_subscription->dest, &npdu_data, &Handler_Transmit_Buffer[0],
            (uint16_t) pdu_len);
    }
    bytes_sent =
        datalink_send_pdu(&cov_subscription->dest, &npdu_data,
        &Handler_Transmit_Buffer[0], pdu_len);
    if (bytes_sent > 0) {
        status = true;
    }

  COV_FAILED:

    return status;
}
Exemple #13
0
/** returns the invoke ID for confirmed request, or zero on failure */
uint8_t Send_Write_Property_Request_Data(
    BACNET_ADDRESS * dest,
    uint16_t max_apdu,
    BACNET_OBJECT_TYPE object_type,
    uint32_t object_instance,
    BACNET_PROPERTY_ID object_property,
    uint8_t * application_data,
    int application_data_len,
    uint8_t priority,
    uint32_t array_index)
{
    BACNET_ADDRESS my_address;
    uint8_t invoke_id = 0;
    int len = 0;
    int pdu_len = 0;
    int bytes_sent = 0;
    BACNET_WRITE_PROPERTY_DATA data;
    BACNET_NPDU_DATA npdu_data;

    if (!dcc_communication_enabled())
        return 0;

    /* is there a tsm available? */
    invoke_id = tsm_next_free_invokeID();
    if (invoke_id) {
        /* encode the NPDU portion of the packet */
        datalink_get_my_address(&my_address);
        npdu_encode_npdu_data(&npdu_data, true, MESSAGE_PRIORITY_NORMAL);
        pdu_len =
            npdu_encode_pdu(&Handler_Transmit_Buffer[0], dest, &my_address,
            &npdu_data);
        /* encode the APDU portion of the packet */
        data.object_type = object_type;
        data.object_instance = object_instance;
        data.object_property = object_property;
        data.array_index = array_index;
        data.application_data_len = application_data_len;
        memcpy(&data.application_data[0], &application_data[0],
            application_data_len);
        data.priority = priority;
        len =
            wp_encode_apdu(&Handler_Transmit_Buffer[pdu_len], invoke_id,
            &data);
        pdu_len += len;
        /* will it fit in the sender?
           note: if there is a bottleneck router in between
           us and the destination, we won't know unless
           we have a way to check for that and update the
           max_apdu in the address binding table. */
        if (pdu_len < max_apdu) {
            tsm_set_confirmed_unsegmented_transaction(invoke_id, dest,
                &npdu_data, &Handler_Transmit_Buffer[0], (uint16_t) pdu_len);
            bytes_sent =
                datalink_send_pdu(dest, &npdu_data,
                &Handler_Transmit_Buffer[0], pdu_len);
#if PRINT_ENABLED
            if (bytes_sent <= 0)
                fprintf(stderr, "Failed to Send WriteProperty Request (%s)!\n",
                    strerror(errno));
#endif
        } else {
            tsm_free_invoke_id(invoke_id);
            invoke_id = 0;
#if PRINT_ENABLED
            fprintf(stderr,
                "Failed to Send WriteProperty Request "
                "(exceeds destination maximum APDU)!\n");
#endif
        }
    } else {
#if PRINT_ENABLED
            fprintf(stderr,
                "Ran out of invoke ids!\n");
#endif
    }

    return invoke_id;
}
Exemple #14
0
uint8_t Send_Atomic_Write_File_Stream(
    uint32_t device_id,
    uint32_t file_instance,
    int fileStartPosition,
    BACNET_OCTET_STRING * fileData)
{
    BACNET_ADDRESS dest;
    BACNET_ADDRESS my_address;
    BACNET_NPDU_DATA npdu_data;
    unsigned max_apdu = 0;
    uint8_t invoke_id = 0;
    bool status = false;
    int len = 0;
    int pdu_len = 0;
    int bytes_sent = 0;
    BACNET_ATOMIC_WRITE_FILE_DATA data;

    /* if we are forbidden to send, don't send! */
    if (!dcc_communication_enabled())
        return 0;

    /* is the device bound? */
    status = address_get_by_device(device_id, &max_apdu, &dest);
    /* is there a tsm available? */
    if (status)
        invoke_id = tsm_next_free_invokeID();
    if (invoke_id) {
        /* load the data for the encoding */
        data.object_type = OBJECT_FILE;
        data.object_instance = file_instance;
        data.access = FILE_STREAM_ACCESS;
        data.type.stream.fileStartPosition = fileStartPosition;
        status = octetstring_copy(&data.fileData[0], fileData);
        if (status) {
            /* encode the NPDU portion of the packet */
            datalink_get_my_address(&my_address);
            npdu_encode_npdu_data(&npdu_data, true, MESSAGE_PRIORITY_NORMAL);
            pdu_len =
                npdu_encode_pdu(&Handler_Transmit_Buffer[0], &dest,
                &my_address, &npdu_data);
            /* encode the APDU portion of the packet */
            len =
                awf_encode_apdu(&Handler_Transmit_Buffer[pdu_len], invoke_id,
                &data);
            pdu_len += len;
            /* will the APDU fit the target device?
               note: if there is a bottleneck router in between
               us and the destination, we won't know unless
               we have a way to check for that and update the
               max_apdu in the address binding table. */
            if ((unsigned) pdu_len <= max_apdu) {
                tsm_set_confirmed_unsegmented_transaction(invoke_id, &dest,
                    &npdu_data, &Handler_Transmit_Buffer[0],
                    (uint16_t) pdu_len);
                bytes_sent =
                    datalink_send_pdu(&dest, &npdu_data,
                    &Handler_Transmit_Buffer[0], pdu_len);
#if PRINT_ENABLED
                if (bytes_sent <= 0)
                    fprintf(stderr,
                        "Failed to Send AtomicWriteFile Request (%s)!\n",
                        strerror(errno));
#endif
            } else {
                tsm_free_invoke_id(invoke_id);
                invoke_id = 0;
#if PRINT_ENABLED
                fprintf(stderr,
                    "Failed to Send AtomicWriteFile Request "
                    "(payload [%d] exceeds destination maximum APDU [%u])!\n",
                    pdu_len, max_apdu);
#endif
            }
        } else {
            tsm_free_invoke_id(invoke_id);
            invoke_id = 0;
#if PRINT_ENABLED
            fprintf(stderr,
                "Failed to Send AtomicWriteFile Request "
                "(payload [%d] exceeds octet string capacity)!\n", pdu_len);
#endif
        }
    }

    return invoke_id;
}
Exemple #15
0
/** Sends a Reinitialize Device (RD) request.
 * @ingroup DMRD
 *
 * @param device_id [in] The index to the device address in our address cache.
 * @param state [in] Specifies the desired state of the device after reinitialization.
 * @param password [in] Optional password, up to 20 chars.
 * @return The invokeID of the transmitted message, or 0 on failure.
 */
uint8_t Send_Reinitialize_Device_Request(
    uint32_t device_id,
    BACNET_REINITIALIZED_STATE state,
    char *password)
{
    BACNET_ADDRESS dest;
    BACNET_ADDRESS my_address;
    unsigned max_apdu = 0;
    uint8_t invoke_id = 0;
    bool status = false;
    int len = 0;
    int pdu_len = 0;
    int bytes_sent = 0;
    BACNET_CHARACTER_STRING password_string;
    BACNET_NPDU_DATA npdu_data;

    /* if we are forbidden to send, don't send! */
    if (!dcc_communication_enabled())
        return 0;

    /* is the device bound? */
    status = address_get_by_device(device_id, &max_apdu, &dest);
    /* is there a tsm available? */
    if (status)
        invoke_id = tsm_next_free_invokeID();
    if (invoke_id) {
        /* encode the NPDU portion of the packet */
        datalink_get_my_address(&my_address);
        npdu_encode_npdu_data(&npdu_data, true, MESSAGE_PRIORITY_NORMAL);
        pdu_len =
            npdu_encode_pdu(&Handler_Transmit_Buffer[0], &dest, &my_address,
            &npdu_data);
        /* encode the APDU portion of the packet */
        characterstring_init_ansi(&password_string, password);
        len =
            rd_encode_apdu(&Handler_Transmit_Buffer[pdu_len], invoke_id, state,
            password ? &password_string : NULL);
        pdu_len += len;
        /* will it fit in the sender?
           note: if there is a bottleneck router in between
           us and the destination, we won't know unless
           we have a way to check for that and update the
           max_apdu in the address binding table. */
        if ((unsigned) pdu_len < max_apdu) {
            tsm_set_confirmed_unsegmented_transaction(invoke_id, &dest,
                &npdu_data, &Handler_Transmit_Buffer[0], (uint16_t) pdu_len);
            bytes_sent =
                datalink_send_pdu(&dest, &npdu_data,
                &Handler_Transmit_Buffer[0], pdu_len);
#if PRINT_ENABLED
            if (bytes_sent <= 0)
                fprintf(stderr,
                    "Failed to Send ReinitializeDevice Request (%s)!\n",
                    strerror(errno));
#endif
        } else {
            tsm_free_invoke_id(invoke_id);
            invoke_id = 0;
#if PRINT_ENABLED
            fprintf(stderr,
                "Failed to Send ReinitializeDevice Request "
                "(exceeds destination maximum APDU)!\n");
#endif
        }
    }

    return invoke_id;
}
Exemple #16
0
/** Sends a Write Property Multiple request.
 * @param pdu [out] Buffer to build the outgoing message into
 * @param max_pdu [in] Length of the pdu buffer.
 * @param device_id [in] ID of the destination device
 * @param write_access_data [in] Ptr to structure with the linked list of
 *        objects and properties to be written.
 * @return invoke id of outgoing message, or 0 if device is not bound or no tsm available
 */
uint8_t Send_Write_Property_Multiple_Request(
    uint8_t * pdu,
    size_t max_pdu,
    uint32_t device_id,
    BACNET_WRITE_ACCESS_DATA * write_access_data)
{
    BACNET_ADDRESS dest;
    BACNET_ADDRESS my_address;
    unsigned max_apdu = 0;
    uint8_t invoke_id = 0;
    bool status = false;
    int len = 0;
    int pdu_len = 0;
    int bytes_sent = 0;
    BACNET_NPDU_DATA npdu_data;

    /* if we are forbidden to send, don't send! */
    if (!dcc_communication_enabled()) {
        return 0;
    }
    /* is the device bound? */
    status = address_get_by_device(device_id, &max_apdu, &dest);
    /* is there a tsm available? */
    if (status) {
        invoke_id = tsm_next_free_invokeID();
    }
    if (invoke_id) {
        /* encode the NPDU portion of the packet */
        datalink_get_my_address(&my_address);
        npdu_encode_npdu_data(&npdu_data, true, MESSAGE_PRIORITY_NORMAL);
        pdu_len = npdu_encode_pdu(&pdu[0], &dest, &my_address,&npdu_data);
        /* encode the APDU portion of the packet */
        len =
            wpm_encode_apdu(&pdu[pdu_len], max_pdu - pdu_len,
            invoke_id, write_access_data);
        pdu_len += len;

        /* will it fit in the sender?
           note: if there is a bottleneck router in between
           us and the destination, we won't know unless
           we have a way to check for that and update the
           max_apdu in the address binding table. */
        if ((unsigned) pdu_len < max_apdu) {
            tsm_set_confirmed_unsegmented_transaction(invoke_id, &dest,
                &npdu_data, &pdu[0], (uint16_t) pdu_len);
            bytes_sent =
                datalink_send_pdu(&dest, &npdu_data,
                &pdu[0], pdu_len);
#if PRINT_ENABLED
            if (bytes_sent <= 0) {
                fprintf(stderr,
                    "Failed to Send WritePropertyMultiple Request (%s)!\n",
                    strerror(errno));
            }
#endif
        } else {
            tsm_free_invoke_id(invoke_id);
            invoke_id = 0;
#if PRINT_ENABLED
            fprintf(stderr,
                "Failed to Send WritePropertyMultiple Request "
                "(exceeds destination maximum APDU)!\n");
#endif
        }
    }

    return invoke_id;
}