/* for debugging... */ void rpm_ack_print_data( BACNET_READ_ACCESS_DATA * rpm_data) { BACNET_OBJECT_PROPERTY_VALUE object_value; /* for bacapp printing */ BACNET_PROPERTY_REFERENCE *listOfProperties; BACNET_APPLICATION_DATA_VALUE *value; bool array_value = false; if (rpm_data) { #if PRINT_ENABLED fprintf(stdout, "%s #%lu\r\n", bactext_object_type_name(rpm_data->object_type), (unsigned long) rpm_data->object_instance); fprintf(stdout, "{\r\n"); #endif listOfProperties = rpm_data->listOfProperties; while (listOfProperties) { #if PRINT_ENABLED if (listOfProperties->propertyIdentifier < 512) { fprintf(stdout, " %s: ", bactext_property_name(listOfProperties-> propertyIdentifier)); } else { fprintf(stdout, " proprietary %u: ", (unsigned) listOfProperties->propertyIdentifier); } #endif if (listOfProperties->propertyArrayIndex != BACNET_ARRAY_ALL) { #if PRINT_ENABLED fprintf(stdout, "[%d]", listOfProperties->propertyArrayIndex); #endif } value = listOfProperties->value; if (value) { #if PRINT_ENABLED if (value->next) { fprintf(stdout, "{"); array_value = true; } else { array_value = false; } #endif object_value.object_type = rpm_data->object_type; object_value.object_instance = rpm_data->object_instance; while (value) { object_value.object_property = listOfProperties->propertyIdentifier; object_value.array_index = listOfProperties->propertyArrayIndex; object_value.value = value; bacapp_print_value(stdout, &object_value); #if PRINT_ENABLED if (value->next) { fprintf(stdout, ",\r\n "); } else { if (array_value) { fprintf(stdout, "}\r\n"); } else { fprintf(stdout, "\r\n"); } } #endif value = value->next; } } else { #if PRINT_ENABLED /* AccessError */ fprintf(stdout, "BACnet Error: %s: %s\r\n", bactext_error_class_name((int) listOfProperties-> error.error_class), bactext_error_code_name((int) listOfProperties-> error.error_code)); #endif } listOfProperties = listOfProperties->next; } #if PRINT_ENABLED fprintf(stdout, "}\r\n"); #endif } }
/** Handler for an Unconfirmed COV Notification. * @ingroup DSCOV * Decodes the received list of Properties to update, * and print them out with the subscription information. * @note Nothing is specified in BACnet about what to do with the * information received from Unconfirmed COV Notifications. * * @param service_request [in] The contents of the service request. * @param service_len [in] The length of the service_request. * @param src [in] BACNET_ADDRESS of the source of the message (unused) */ void handler_ucov_notification( uint8_t * service_request, uint16_t service_len, BACNET_ADDRESS * src) { BACNET_COV_DATA cov_data; BACNET_PROPERTY_VALUE property_value[MAX_COV_PROPERTIES]; BACNET_PROPERTY_VALUE *pProperty_value = NULL; int len = 0; unsigned index = 0; /* src not needed for this application */ src = src; /* create linked list to store data if more than one property value is expected */ pProperty_value = &property_value[0]; while (pProperty_value) { index++; if (index < MAX_COV_PROPERTIES) { pProperty_value->next = &property_value[index]; } else { pProperty_value->next = NULL; } pProperty_value = pProperty_value->next; } cov_data.listOfValues = &property_value[0]; #if PRINT_ENABLED fprintf(stderr, "UCOV: Received Notification!\n"); #endif /* decode the service request only */ len = cov_notify_decode_service_request(service_request, service_len, &cov_data); #if PRINT_ENABLED if (len > 0) { fprintf(stderr, "UCOV: PID=%u ", cov_data.subscriberProcessIdentifier); fprintf(stderr, "instance=%u ", cov_data.initiatingDeviceIdentifier); fprintf(stderr, "%s %u ", bactext_object_type_name(cov_data.monitoredObjectIdentifier.type), cov_data.monitoredObjectIdentifier.instance); fprintf(stderr, "time remaining=%u seconds ", cov_data.timeRemaining); fprintf(stderr, "\n"); pProperty_value = &property_value[0]; while (pProperty_value) { fprintf(stderr, "UCOV: "); if (pProperty_value->propertyIdentifier < 512) { fprintf(stderr, "%s ", bactext_property_name (pProperty_value->propertyIdentifier)); } else { fprintf(stderr, "proprietary %u ", pProperty_value->propertyIdentifier); } if (pProperty_value->propertyArrayIndex != BACNET_ARRAY_ALL) { fprintf(stderr, "%u ", pProperty_value->propertyArrayIndex); } fprintf(stderr, "\n"); pProperty_value = pProperty_value->next; } } else { fprintf(stderr, "UCOV: Unable to decode service request!\n"); } #endif }
/** Handler for an Confirmed COV Notification. * @ingroup DSCOV * Decodes the received list of Properties to update, * and print them out with the subscription information. * @note Nothing is specified in BACnet about what to do with the * information received from Confirmed COV Notifications. * * @param service_request [in] The contents of the service request. * @param service_len [in] The length of the service_request. * @param src [in] BACNET_ADDRESS of the source of the message * @param service_data [in] The BACNET_CONFIRMED_SERVICE_DATA information * decoded from the APDU header of this message. */ void handler_ccov_notification( uint8_t * service_request, uint16_t service_len, BACNET_ADDRESS * src, BACNET_CONFIRMED_SERVICE_DATA * service_data) { BACNET_NPDU_DATA npdu_data; BACNET_COV_DATA cov_data; BACNET_PROPERTY_VALUE property_value[MAX_COV_PROPERTIES]; BACNET_PROPERTY_VALUE *pProperty_value = NULL; unsigned index = 0; int len = 0; int pdu_len = 0; int bytes_sent = 0; BACNET_ADDRESS my_address; /* create linked list to store data if more than one property value is expected */ pProperty_value = &property_value[0]; while (pProperty_value) { index++; if (index < MAX_COV_PROPERTIES) { pProperty_value->next = &property_value[index]; } else { pProperty_value->next = NULL; } pProperty_value = pProperty_value->next; } cov_data.listOfValues = &property_value[0]; /* encode the NPDU portion of the packet */ 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], src, &my_address, &npdu_data); #if PRINT_ENABLED fprintf(stderr, "CCOV: Received Notification!\n"); #endif if (service_data->segmented_message) { len = abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id, ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, true); #if PRINT_ENABLED fprintf(stderr, "CCOV: Segmented message. Sending Abort!\n"); #endif goto CCOV_ABORT; } /* decode the service request only */ len = cov_notify_decode_service_request(service_request, service_len, &cov_data); #if PRINT_ENABLED if (len > 0) { fprintf(stderr, "CCOV: PID=%u ", cov_data.subscriberProcessIdentifier); fprintf(stderr, "instance=%u ", cov_data.initiatingDeviceIdentifier); fprintf(stderr, "%s %u ", bactext_object_type_name(cov_data.monitoredObjectIdentifier.type), cov_data.monitoredObjectIdentifier.instance); fprintf(stderr, "time remaining=%u seconds ", cov_data.timeRemaining); fprintf(stderr, "\n"); pProperty_value = &property_value[0]; while (pProperty_value) { fprintf(stderr, "CCOV: "); if (pProperty_value->propertyIdentifier < 512) { fprintf(stderr, "%s ", bactext_property_name (pProperty_value->propertyIdentifier)); } else { fprintf(stderr, "proprietary %u ", pProperty_value->propertyIdentifier); } if (pProperty_value->propertyArrayIndex != BACNET_ARRAY_ALL) { fprintf(stderr, "%u ", pProperty_value->propertyArrayIndex); } fprintf(stderr, "\n"); pProperty_value = pProperty_value->next; } } #endif /* bad decoding or something we didn't understand - send an abort */ if (len <= 0) { len = abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id, ABORT_REASON_OTHER, true); #if PRINT_ENABLED fprintf(stderr, "CCOV: Bad Encoding. Sending Abort!\n"); #endif goto CCOV_ABORT; } else { len = encode_simple_ack(&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id, SERVICE_CONFIRMED_COV_NOTIFICATION); #if PRINT_ENABLED fprintf(stderr, "CCOV: Sending Simple Ack!\n"); #endif } CCOV_ABORT: pdu_len += len; bytes_sent = datalink_send_pdu(src, &npdu_data, &Handler_Transmit_Buffer[0], pdu_len); #if PRINT_ENABLED if (bytes_sent <= 0) { fprintf(stderr, "CCOV: Failed to send PDU (%s)!\n", strerror(errno)); } #else bytes_sent = bytes_sent; #endif return; }