diff --git a/bacnet-stack/handlers.c b/bacnet-stack/handlers.c index 69a97aea..5819d6f9 100644 --- a/bacnet-stack/handlers.c +++ b/bacnet-stack/handlers.c @@ -136,7 +136,7 @@ void Send_WhoIs(void) fprintf(stderr,"Failed to Send Who-Is Request (%s)!\n", strerror(errno)); } -// returns false if device is not bound +// returns false if device is not bound or no tsm available bool Send_Read_Property_Request( uint32_t device_id, // destination device BACNET_OBJECT_TYPE object_type, @@ -153,7 +153,11 @@ bool Send_Read_Property_Request( int bytes_sent = 0; BACNET_READ_PROPERTY_DATA data; + /* is the device bound? */ status = address_get_by_device(device_id, &max_apdu, &dest); + /* is there a tsm available? */ + if (status) + status = tsm_transaction_available(); if (status) { datalink_get_my_address(&my_address); @@ -174,6 +178,11 @@ bool Send_Read_Property_Request( &Tx_Buf[pdu_len], invoke_id, &data); + /* 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( diff --git a/bacnet-stack/ports/linux/main.c b/bacnet-stack/ports/linux/main.c index 62cc07e1..4065c4ed 100644 --- a/bacnet-stack/ports/linux/main.c +++ b/bacnet-stack/ports/linux/main.c @@ -97,6 +97,7 @@ static void LocalIAmHandler( static void Read_Properties(void) { uint32_t device_id = 0; + bool status = false; unsigned max_apdu = 0; BACNET_ADDRESS src; bool next_device = false; @@ -108,15 +109,41 @@ static void Read_Properties(void) to have all the properties listed here. */ const int object_props[] = { - 75,77,79,112,121,120,70,44,12,98,95,97,96, - 62,107,57,56,119,24,10,11,73,116,64,63,30, - 514,515, - /* note: 76 is missing cause we get it special: - 76 is the object list, and reading index 0 - gives us the number of objects in the list, + 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 }; @@ -128,25 +155,25 @@ static void Read_Properties(void) next_device = true; else { - if (Send_Read_Property_Request( + /* 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)) - { - /* 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. */ + BACNET_ARRAY_ALL); + if (status) property++; - } } } else next_device = true; if (next_device) { + next_device = false; index++; if (index >= MAX_ADDRESS_CACHE) index = 0; diff --git a/bacnet-stack/ports/win32/bacnet.ide b/bacnet-stack/ports/win32/bacnet.ide index b90772d3..1a1e74cc 100644 Binary files a/bacnet-stack/ports/win32/bacnet.ide and b/bacnet-stack/ports/win32/bacnet.ide differ diff --git a/bacnet-stack/ports/win32/bip-init.c b/bacnet-stack/ports/win32/bip-init.c index 5aeb083f..5dc0d1e0 100644 --- a/bacnet-stack/ports/win32/bip-init.c +++ b/bacnet-stack/ports/win32/bip-init.c @@ -172,6 +172,9 @@ bool bip_init(void) (const struct sockaddr*)&sin, sizeof(struct sockaddr)); if (rv < 0) { + fprintf(stderr,"bip: failed to bind to %s port %hd\n", + inet_ntoa(sin.sin_addr), + bip_get_port()); close(sock_fd); bip_set_socket(-1); return false; diff --git a/bacnet-stack/ports/win32/main.c b/bacnet-stack/ports/win32/main.c index 5b817679..db16c121 100644 --- a/bacnet-stack/ports/win32/main.c +++ b/bacnet-stack/ports/win32/main.c @@ -46,19 +46,50 @@ static uint8_t Rx_Buf[MAX_MPDU] = {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 + /* 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[] = { - 75,77,79,112,121,120,70,44,12,98,95,97,96, - 62,107,57,56,119,24,10,11,73,116,64,63,30, + 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 cause + we need to get it with an index method since + the list could be very large */ + /* some proprietary properties */ 514,515, - // note: 76 is missing cause we get it special below + /* end of list */ -1 }; @@ -70,19 +101,21 @@ static void Read_Properties(void) next_device = true; else { - (void)Send_Read_Property_Request( + status = Send_Read_Property_Request( device_id, // destination device OBJECT_DEVICE, device_id, object_props[property], BACNET_ARRAY_ALL); - property++; + if (status) + property++; } } else next_device = true; if (next_device) { + next_device = false; index++; if (index >= MAX_ADDRESS_CACHE) index = 0; @@ -186,7 +219,7 @@ static void print_address( static void print_address_cache(void) { - unsigned i,j; + int i,j; BACNET_ADDRESS address; uint32_t device_id = 0; unsigned max_apdu = 0; @@ -235,7 +268,6 @@ int main(int argc, char *argv[]) for (;;) { // input - //Read_Properties(); // returns 0 bytes on timeout pdu_len = bip_receive( diff --git a/bacnet-stack/tsm.c b/bacnet-stack/tsm.c index 6cca0451..1b7aedd6 100644 --- a/bacnet-stack/tsm.c +++ b/bacnet-stack/tsm.c @@ -127,6 +127,7 @@ uint8_t tsm_next_free_invokeID(void) found = true; invokeID = current_invokeID; } + /* update for the next call or check */ current_invokeID++; // skip zero - we treat that internally as invalid or no free if (current_invokeID == 0)