int BacnetReadProperty( int deviceInstanceNumber, int objectType, int objectInstanceNumber, int objectProperty, int objectIndex) { if (!isReadPropertyHandlerRegistered) { /* handle the data coming back from confirmed requests */ apdu_set_confirmed_ack_handler(SERVICE_CONFIRMED_READ_PROPERTY, My_Read_Property_Ack_Handler); /* handle any errors coming back */ apdu_set_error_handler(SERVICE_CONFIRMED_READ_PROPERTY, My_Error_Handler); /* indicate that handlers are now registered */ isReadPropertyHandlerRegistered = true; } /* Send the message out */ Request_Invoke_ID = Send_Read_Property_Request(deviceInstanceNumber, objectType, objectInstanceNumber, objectProperty, objectIndex); Wait_For_Answer_Or_Timeout(100, waitAnswer); int isFailure = Error_Detected; Error_Detected = 0; return isFailure; }
static void Read_Properties( void) { uint32_t device_id = 0; bool status = false; unsigned max_apdu = 0; BACNET_ADDRESS src; bool next_device = false; static unsigned index = 0; static unsigned property = 0; /* list of required (and some optional and proprietary) properties in the Device Object. Note that this demo tests for error messages so that the device doesn't have to have all the properties listed here. */ const int object_props[] = { PROP_OBJECT_IDENTIFIER, PROP_OBJECT_NAME, PROP_OBJECT_TYPE, PROP_SYSTEM_STATUS, PROP_VENDOR_NAME, PROP_VENDOR_IDENTIFIER, PROP_MODEL_NAME, PROP_FIRMWARE_REVISION, PROP_APPLICATION_SOFTWARE_VERSION, PROP_PROTOCOL_VERSION, PROP_PROTOCOL_CONFORMANCE_CLASS, PROP_PROTOCOL_SERVICES_SUPPORTED, PROP_PROTOCOL_OBJECT_TYPES_SUPPORTED, PROP_MAX_APDU_LENGTH_ACCEPTED, PROP_SEGMENTATION_SUPPORTED, PROP_LOCAL_TIME, PROP_LOCAL_DATE, PROP_UTC_OFFSET, PROP_DAYLIGHT_SAVINGS_STATUS, PROP_APDU_SEGMENT_TIMEOUT, PROP_APDU_TIMEOUT, PROP_NUMBER_OF_APDU_RETRIES, PROP_TIME_SYNCHRONIZATION_RECIPIENTS, PROP_MAX_MASTER, PROP_MAX_INFO_FRAMES, PROP_DEVICE_ADDRESS_BINDING, /* note: PROP_OBJECT_LIST is missing because the result can be very large. Read index 0 which gives us the number of objects in the list, and then we can read index 1, 2.. n one by one, rather than trying to read the entire object list in one message. */ /* some proprietary properties */ 514, 515, /* end of list */ -1 }; if (address_count()) { if (address_get_by_index(index, &device_id, &max_apdu, &src)) { if (object_props[property] < 0) next_device = true; else { /* note: if we wanted to do this synchronously, we would get the invoke ID from the sending of the request, and wait until we got the reply with matching invoke ID or the TSM of the invoke ID expired. This demo is doing things asynchronously. */ status = Send_Read_Property_Request(device_id, /* destination device */ OBJECT_DEVICE, device_id, object_props[property], BACNET_ARRAY_ALL); if (status) property++; } } else next_device = true; if (next_device) { next_device = false; index++; if (index >= MAX_ADDRESS_CACHE) index = 0; property = 0; } } return; }
int publish_data(adapter_t *adapter) { static uint8_t rx_buf[MAX_MPDU] = {0}; bacnet_context_t *context = (bacnet_context_t*) (adapter -> context); bacnet_device_t *device; time_t current_seconds, elapsed_seconds = 0; int pdu_len; char *time_str, *node_id; time_t last_seconds,timeout_seconds; unsigned timeout = 100; BACNET_ADDRESS src = { 0 }; unsigned max_apdu = 0; mio_stanza_t *item; mio_response_t *publish_response; for (device = context -> node_devices; device; device = device -> nodemap.next) { time_str = mio_timestamp_create(); item = mio_pubsub_item_data_new(adapter -> connection); node_id = device -> node_id; last_seconds = time(NULL); timeout_seconds = (apdu_timeout() / 1000) * apdu_retries(); //if (!found) found = address_bind_request(device -> instance, &max_apdu, &target_address); if (!found) { Send_WhoIs(device -> instance, device -> instance); } while (!found) { current_seconds = time(NULL); if (current_seconds != last_seconds) tsm_timer_milliseconds((uint16_t) ((current_seconds - last_seconds) * 1000)); if (!found) { found = address_bind_request(device -> instance, &max_apdu,&target_address); } if (!found) { elapsed_seconds += (current_seconds - last_seconds); if (elapsed_seconds > timeout_seconds) { printf("\rError: APDU Timeout!\r\n"); return 1; } } pdu_len = datalink_receive(&src, &rx_buf[0], MAX_MPDU,timeout); if (pdu_len) { npdu_handler(&src, &rx_buf[0], pdu_len); } last_seconds = current_seconds; } int i; printf("n_objects %d\n", device -> n_objects); for ( i = 0; i < device -> n_objects; i++) { request_invoke_id = 0; while(TRUE) { printf("true\n"); if (found) { if (request_invoke_id == 0) { request_invoke_id = Send_Read_Property_Request( device->instance, device -> obj_types[i], device -> obj_ids[i], 85, -1); } else if (tsm_invoke_id_free(request_invoke_id)) break; else if (tsm_invoke_id_failed(request_invoke_id)) { fprintf(stderr,"\rError: TSM Timeout!\r\n"); tsm_free_invoke_id(request_invoke_id); return 1; } } pdu_len = datalink_receive(&src, &rx_buf[0], MAX_MPDU,timeout); if (pdu_len) { npdu_handler(&src, &rx_buf[0], pdu_len); } last_seconds = current_seconds; } if (error_detected) { error_detected = 0; return 1; } else { if (strcmp(value,"active") == 0) mio_item_transducer_value_add(item, NULL, device -> obj_names[i] , "1", value, time_str); else if (strcmp(value,"inactive") == 0) mio_item_transducer_value_add(item, NULL, device -> obj_names[i] , "0",value, time_str); else mio_item_transducer_value_add(item, NULL, device -> obj_names[i] , value, value, time_str); } } publish_response = mio_response_new(); while (adapter -> connection -> xmpp_conn -> state != XMPP_STATE_CONNECTED) usleep(1000); mio_item_publish_data(adapter -> connection,item,node_id,publish_response); free(time_str); mio_response_print(publish_response); mio_response_free(publish_response); mio_stanza_free(item); } return 0; }
static void Read_Properties( void) { uint32_t device_id = 0; bool status = false; unsigned max_apdu = 0; BACNET_ADDRESS src; bool next_device = false; static unsigned index = 0; static unsigned property = 0; /* list of required (and some optional) properties in the Device Object note: you could just loop through all the properties in all the objects. */ const int object_props[] = { PROP_OBJECT_IDENTIFIER, PROP_OBJECT_NAME, PROP_OBJECT_TYPE, PROP_SYSTEM_STATUS, PROP_VENDOR_NAME, PROP_VENDOR_IDENTIFIER, PROP_MODEL_NAME, PROP_FIRMWARE_REVISION, PROP_APPLICATION_SOFTWARE_VERSION, PROP_PROTOCOL_VERSION, PROP_PROTOCOL_SERVICES_SUPPORTED, PROP_PROTOCOL_OBJECT_TYPES_SUPPORTED, PROP_MAX_APDU_LENGTH_ACCEPTED, PROP_SEGMENTATION_SUPPORTED, PROP_LOCAL_TIME, PROP_LOCAL_DATE, PROP_UTC_OFFSET, PROP_DAYLIGHT_SAVINGS_STATUS, PROP_APDU_SEGMENT_TIMEOUT, PROP_APDU_TIMEOUT, PROP_NUMBER_OF_APDU_RETRIES, PROP_TIME_SYNCHRONIZATION_RECIPIENTS, PROP_MAX_MASTER, PROP_MAX_INFO_FRAMES, PROP_DEVICE_ADDRESS_BINDING, /* note: PROP_OBJECT_LIST is missing cause we need to get it with an index method since the list could be very large */ /* some proprietary properties */ 514, 515, /* end of list */ -1 }; if (address_count()) { if (address_get_by_index(index, &device_id, &max_apdu, &src)) { if (object_props[property] < 0) next_device = true; else { status = Send_Read_Property_Request(device_id, /* destination device */ OBJECT_DEVICE, device_id, object_props[property], BACNET_ARRAY_ALL); if (status) property++; } } else next_device = true; if (next_device) { next_device = false; index++; if (index >= MAX_ADDRESS_CACHE) index = 0; property = 0; } } return; }