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 }
/** 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); }
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 }
/** * 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 }
/** 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); }
/** 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; }
/** 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 }
/* 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 }
/* 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; }
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; }
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; }
/** 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; }
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; }
/** 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; }
/** 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; }