diff --git a/bacnet-stack/demo/dcc/main.c b/bacnet-stack/demo/dcc/main.c index cf1f57bd..ef380b7e 100644 --- a/bacnet-stack/demo/dcc/main.c +++ b/bacnet-stack/demo/dcc/main.c @@ -191,6 +191,7 @@ int main( address_init(); Init_Service_Handlers(); dlenv_init(); + atexit(datalink_cleanup); /* configure the timeout values */ last_seconds = time(NULL); timeout_seconds = (apdu_timeout() / 1000) * apdu_retries(); diff --git a/bacnet-stack/demo/epics/main.c b/bacnet-stack/demo/epics/main.c index f1070883..39b70927 100644 --- a/bacnet-stack/demo/epics/main.c +++ b/bacnet-stack/demo/epics/main.c @@ -1254,6 +1254,7 @@ int main( address_init(); Init_Service_Handlers(); dlenv_init(); + atexit(datalink_cleanup); /* configure the timeout values */ current_seconds = time(NULL); @@ -1619,6 +1620,7 @@ int main( printf("End of BACnet Protocol Implementation Conformance Statement\r\n"); printf("\r\n"); } + return 0; } diff --git a/bacnet-stack/demo/gateway/main.c b/bacnet-stack/demo/gateway/main.c index 8be99ebf..c34eeadf 100644 --- a/bacnet-stack/demo/gateway/main.c +++ b/bacnet-stack/demo/gateway/main.c @@ -230,17 +230,6 @@ void Initialize_Device_Addresses( } } - -/** Handler registered with atexit() inside main function to, well, cleanup. - * Especially if we don't end normally. - * @see datalink_cleanup - */ -static void cleanup( - void) -{ - datalink_cleanup(); -} - /** Main function of server demo. * * @see Device_Set_Object_Instance_Number, dlenv_init, Send_I_Am, @@ -289,9 +278,9 @@ int main( first_object_instance, MAX_APDU); Init_Service_Handlers(first_object_instance); dlenv_init(); + atexit(datalink_cleanup); Devices_Init(first_object_instance); Initialize_Device_Addresses(); - atexit(cleanup); #ifdef BACNET_TEST_VMAC /* initialize vmac table and router device */ diff --git a/bacnet-stack/demo/iamrouter/main.c b/bacnet-stack/demo/iamrouter/main.c index 716c402a..1c682fac 100644 --- a/bacnet-stack/demo/iamrouter/main.c +++ b/bacnet-stack/demo/iamrouter/main.c @@ -146,6 +146,7 @@ int main( Init_Service_Handlers(); address_init(); dlenv_init(); + atexit(datalink_cleanup); /* send the request */ Send_I_Am_Router_To_Network(Target_Router_Networks); diff --git a/bacnet-stack/demo/initrouter/main.c b/bacnet-stack/demo/initrouter/main.c index 03e1b10d..bb731a76 100644 --- a/bacnet-stack/demo/initrouter/main.c +++ b/bacnet-stack/demo/initrouter/main.c @@ -322,6 +322,7 @@ int main( Init_Service_Handlers(); address_init(); dlenv_init(); + atexit(datalink_cleanup); /* configure the timeout values */ last_seconds = time(NULL); timeout_seconds = apdu_timeout() / 1000; diff --git a/bacnet-stack/demo/ptransfer/main.c b/bacnet-stack/demo/ptransfer/main.c index 6d1e1a5e..2ad3934b 100644 --- a/bacnet-stack/demo/ptransfer/main.c +++ b/bacnet-stack/demo/ptransfer/main.c @@ -222,6 +222,7 @@ int main( address_init(); Init_Service_Handlers(); dlenv_init(); + atexit(datalink_cleanup); /* configure the timeout values */ last_seconds = time(NULL); timeout_seconds = (apdu_timeout() / 1000) * apdu_retries(); @@ -380,7 +381,6 @@ int main( last_seconds = current_seconds; } } - if (Error_Detected) return 1; return 0; diff --git a/bacnet-stack/demo/readfile/main.c b/bacnet-stack/demo/readfile/main.c index 5d10af92..416ace96 100644 --- a/bacnet-stack/demo/readfile/main.c +++ b/bacnet-stack/demo/readfile/main.c @@ -247,6 +247,7 @@ int main( address_init(); Init_Service_Handlers(); dlenv_init(); + atexit(datalink_cleanup); /* configure the timeout values */ last_seconds = time(NULL); timeout_seconds = (apdu_timeout() / 1000) * apdu_retries(); diff --git a/bacnet-stack/demo/readprop/main.c b/bacnet-stack/demo/readprop/main.c index 1e68f0ee..62e5222f 100644 --- a/bacnet-stack/demo/readprop/main.c +++ b/bacnet-stack/demo/readprop/main.c @@ -254,6 +254,7 @@ int main( address_init(); Init_Service_Handlers(); dlenv_init(); + atexit(datalink_cleanup); /* configure the timeout values */ last_seconds = time(NULL); timeout_seconds = (apdu_timeout() / 1000) * apdu_retries(); diff --git a/bacnet-stack/demo/readpropm/main.c b/bacnet-stack/demo/readpropm/main.c index 784ca2b2..57a22b3a 100644 --- a/bacnet-stack/demo/readpropm/main.c +++ b/bacnet-stack/demo/readpropm/main.c @@ -400,6 +400,7 @@ int main( address_init(); Init_Service_Handlers(); dlenv_init(); + atexit(datalink_cleanup); /* configure the timeout values */ last_seconds = time(NULL); timeout_seconds = (apdu_timeout() / 1000) * apdu_retries(); diff --git a/bacnet-stack/demo/readrange/main.c b/bacnet-stack/demo/readrange/main.c index 140427a6..7a457af3 100644 --- a/bacnet-stack/demo/readrange/main.c +++ b/bacnet-stack/demo/readrange/main.c @@ -249,6 +249,7 @@ int main( address_init(); Init_Service_Handlers(); dlenv_init(); + atexit(datalink_cleanup); /* configure the timeout values */ last_seconds = time(NULL); timeout_seconds = (apdu_timeout() / 1000) * apdu_retries(); diff --git a/bacnet-stack/demo/reinit/main.c b/bacnet-stack/demo/reinit/main.c index c07e9cf6..e4791323 100644 --- a/bacnet-stack/demo/reinit/main.c +++ b/bacnet-stack/demo/reinit/main.c @@ -185,6 +185,7 @@ int main( address_init(); Init_Service_Handlers(); dlenv_init(); + atexit(datalink_cleanup); /* configure the timeout values */ last_seconds = time(NULL); timeout_seconds = (apdu_timeout() / 1000) * apdu_retries(); diff --git a/bacnet-stack/demo/scov/main.c b/bacnet-stack/demo/scov/main.c index 7af140fc..896734cc 100644 --- a/bacnet-stack/demo/scov/main.c +++ b/bacnet-stack/demo/scov/main.c @@ -300,6 +300,7 @@ int main( address_init(); Init_Service_Handlers(); dlenv_init(); + atexit(datalink_cleanup); /* configure the timeout values */ last_seconds = time(NULL); timeout_seconds = (apdu_timeout() / 1000) * apdu_retries(); diff --git a/bacnet-stack/demo/server/main.c b/bacnet-stack/demo/server/main.c index 0c0f9e6e..2abc7720 100644 --- a/bacnet-stack/demo/server/main.c +++ b/bacnet-stack/demo/server/main.c @@ -131,16 +131,6 @@ static void Init_Service_Handlers( #endif /* defined(INTRINSIC_REPORTING) */ } -/** Handler registered with atexit() inside main function to, well, cleanup. - * Especially if we don't end normally. - * @see datalink_cleanup - */ -static void cleanup( - void) -{ - datalink_cleanup(); -} - /** Main function of server demo. * * @see Device_Set_Object_Instance_Number, dlenv_init, Send_I_Am, @@ -177,7 +167,7 @@ int main( Device_Object_Instance_Number(), MAX_APDU); Init_Service_Handlers(); dlenv_init(); - atexit(cleanup); + atexit(datalink_cleanup); /* configure the timeout values */ last_seconds = time(NULL); /* broadcast an I-Am on startup */ @@ -231,6 +221,7 @@ int main( /* blink LEDs, Turn on or off outputs, etc */ } + return 0; } diff --git a/bacnet-stack/demo/timesync/main.c b/bacnet-stack/demo/timesync/main.c index 0625c78c..7d58db03 100644 --- a/bacnet-stack/demo/timesync/main.c +++ b/bacnet-stack/demo/timesync/main.c @@ -148,6 +148,7 @@ int main( Device_Set_Object_Instance_Number(BACNET_MAX_INSTANCE); Init_Service_Handlers(); dlenv_init(); + atexit(datalink_cleanup); /* configure the timeout values */ last_seconds = time(NULL); timeout_seconds = apdu_timeout() / 1000; diff --git a/bacnet-stack/demo/ucov/main.c b/bacnet-stack/demo/ucov/main.c index c2148b2a..d6660a90 100644 --- a/bacnet-stack/demo/ucov/main.c +++ b/bacnet-stack/demo/ucov/main.c @@ -192,6 +192,7 @@ int main( Device_Set_Object_Instance_Number(BACNET_MAX_INSTANCE); Init_Service_Handlers(); dlenv_init(); + atexit(datalink_cleanup); Send_UCOV_Notify(&Handler_Transmit_Buffer[0], &cov_data); return 0; diff --git a/bacnet-stack/demo/uptransfer/main.c b/bacnet-stack/demo/uptransfer/main.c index 344dc6ab..f697aa0a 100644 --- a/bacnet-stack/demo/uptransfer/main.c +++ b/bacnet-stack/demo/uptransfer/main.c @@ -277,6 +277,7 @@ int main( address_init(); Init_Service_Handlers(); dlenv_init(); + atexit(datalink_cleanup); /* configure the timeout values */ last_seconds = time(NULL); timeout_seconds = (apdu_timeout() / 1000) * apdu_retries(); diff --git a/bacnet-stack/demo/whohas/main.c b/bacnet-stack/demo/whohas/main.c index 7bb936eb..aa7d94db 100644 --- a/bacnet-stack/demo/whohas/main.c +++ b/bacnet-stack/demo/whohas/main.c @@ -153,6 +153,7 @@ int main( Device_Set_Object_Instance_Number(BACNET_MAX_INSTANCE); Init_Service_Handlers(); dlenv_init(); + atexit(datalink_cleanup); /* configure the timeout values */ last_seconds = time(NULL); timeout_seconds = apdu_timeout() / 1000; diff --git a/bacnet-stack/demo/whois/main.c b/bacnet-stack/demo/whois/main.c index 77d75975..36f5b208 100644 --- a/bacnet-stack/demo/whois/main.c +++ b/bacnet-stack/demo/whois/main.c @@ -234,6 +234,7 @@ int main( Init_Service_Handlers(); address_init(); dlenv_init(); + atexit(datalink_cleanup); /* configure the timeout values */ last_seconds = time(NULL); timeout_seconds = apdu_timeout() / 1000; diff --git a/bacnet-stack/demo/whoisrouter/main.c b/bacnet-stack/demo/whoisrouter/main.c index a3b741eb..991eb274 100644 --- a/bacnet-stack/demo/whoisrouter/main.c +++ b/bacnet-stack/demo/whoisrouter/main.c @@ -290,6 +290,7 @@ int main( Init_Service_Handlers(); address_init(); dlenv_init(); + atexit(datalink_cleanup); /* configure the timeout values */ last_seconds = time(NULL); timeout_seconds = apdu_timeout() / 1000; diff --git a/bacnet-stack/demo/writefile/main.c b/bacnet-stack/demo/writefile/main.c index 3ccd18dc..533e15c5 100644 --- a/bacnet-stack/demo/writefile/main.c +++ b/bacnet-stack/demo/writefile/main.c @@ -204,6 +204,7 @@ int main( address_init(); Init_Service_Handlers(); dlenv_init(); + atexit(datalink_cleanup); /* configure the timeout values */ last_seconds = time(NULL); timeout_seconds = (apdu_timeout() / 1000) * apdu_retries(); diff --git a/bacnet-stack/demo/writeprop/main.c b/bacnet-stack/demo/writeprop/main.c index 61bca2b5..d7b6ad8a 100644 --- a/bacnet-stack/demo/writeprop/main.c +++ b/bacnet-stack/demo/writeprop/main.c @@ -326,6 +326,7 @@ int main( address_init(); Init_Service_Handlers(); dlenv_init(); + atexit(datalink_cleanup); /* configure the timeout values */ last_seconds = time(NULL); timeout_seconds = (apdu_timeout() / 1000) * apdu_retries(); diff --git a/bacnet-stack/include/bip.h b/bacnet-stack/include/bip.h index bb9e3c66..232845c2 100644 --- a/bacnet-stack/include/bip.h +++ b/bacnet-stack/include/bip.h @@ -58,10 +58,10 @@ extern "C" { on Windows, ifname is the dotted ip address of the interface */ bool bip_init( char *ifname); - - /* normal functions... */ void bip_cleanup( void); + + /* common BACnet/IP functions */ void bip_set_socket( int sock_fd); int bip_socket( @@ -122,12 +122,12 @@ extern "C" { #ifdef __cplusplus } #endif /* __cplusplus */ -/** @defgroup DLBIP BACnet/IP DataLink Network Layer +/** @defgroup DLBIP BACnet/IP DataLink Network Layer * @ingroup DataLink * Implementation of the Network Layer using BACnet/IP as the transport, as * described in Annex J. * The functions described here fulfill the roles defined generically at the * DataLink level by serving as the implementation of the function templates. - * + * */ #endif diff --git a/bacnet-stack/ports/linux/bip-init.c b/bacnet-stack/ports/linux/bip-init.c index 6ef8765f..4d5b2695 100644 --- a/bacnet-stack/ports/linux/bip-init.c +++ b/bacnet-stack/ports/linux/bip-init.c @@ -98,7 +98,7 @@ static int get_local_address_ioctl( /** Gets the local IP address and local broadcast address from the system, * and saves it into the BACnet/IP data structures. - * + * * @param ifname [in] The named interface to use for the network layer. * Eg, for Linux, ifname is eth0, ath0, arc0, and others. */ @@ -140,12 +140,11 @@ static void bip_set_interface( * -# Opens a UDP socket * -# Configures the socket for sending and receiving * -# Configures the socket so it can send broadcasts - * -# Binds the socket to the local IP address at the specified port for + * -# Binds the socket to the local IP address at the specified port for * BACnet/IP (by default, 0xBAC0 = 47808). - * + * * @note For Linux, ifname is eth0, ath0, arc0, and others. - For Windows, ifname is the dotted ip address of the interface. - + * * @param ifname [in] The named interface to use for the network layer. * If NULL, the "eth0" interface is assigned. * @return True if the socket is successfully opened for BACnet/IP, @@ -204,6 +203,23 @@ bool bip_init( return true; } +/** Cleanup and close out the BACnet/IP services by closing the socket. + * @ingroup DLBIP + */ +void bip_cleanup( + void) +{ + int sock_fd = 0; + + if (bip_valid()) { + sock_fd = bip_socket(); + close(sock_fd); + } + bip_set_socket(-1); + + return; +} + /** Get the netmask of the BACnet/IP's interface via an ioctl() call. * @param netmask [out] The netmask, in host order. * @return 0 on success, else the error from the ioctl() call. diff --git a/bacnet-stack/ports/win32/bip-init.c b/bacnet-stack/ports/win32/bip-init.c index 41d8e5b3..4914b042 100644 --- a/bacnet-stack/ports/win32/bip-init.c +++ b/bacnet-stack/ports/win32/bip-init.c @@ -173,13 +173,6 @@ static void set_broadcast_address( #endif } -static void cleanup( - void) -{ - WSACleanup(); -} - - /* on Windows, ifname is the dotted ip address of the interface */ void bip_set_interface( char *ifname) @@ -318,6 +311,23 @@ static char *winsock_error_code_text( } } +/** Initialize the BACnet/IP services at the given interface. + * @ingroup DLBIP + * -# Gets the local IP address and local broadcast address from the system, + * and saves it into the BACnet/IP data structures. + * -# Opens a UDP socket + * -# Configures the socket for sending and receiving + * -# Configures the socket so it can send broadcasts + * -# Binds the socket to the local IP address at the specified port for + * BACnet/IP (by default, 0xBAC0 = 47808). + * + * @note For Windows, ifname is the dotted ip address of the interface. + * + * @param ifname [in] The named interface to use for the network layer. + * If NULL, the "eth0" interface is assigned. + * @return True if the socket is successfully opened for BACnet/IP, + * else False if the socket functions fail. + */ bool bip_init( char *ifname) { @@ -339,7 +349,7 @@ bool bip_init( Code, winsock_error_code_text(Code)); exit(1); } - atexit(cleanup); + atexit(bip_cleanup); if (ifname) bip_set_interface(ifname); @@ -443,3 +453,21 @@ bool bip_init( return true; } + +/** Cleanup and close out the BACnet/IP services by closing the socket. + * @ingroup DLBIP + */ +void bip_cleanup( + void) +{ + int sock_fd = 0; + + if (bip_valid()) { + sock_fd = bip_socket(); + close(sock_fd); + } + bip_set_socket(-1); + WSACleanup(); + + return; +} diff --git a/bacnet-stack/src/bip.c b/bacnet-stack/src/bip.c index 71e468c3..a71ef8ba 100644 --- a/bacnet-stack/src/bip.c +++ b/bacnet-stack/src/bip.c @@ -79,19 +79,6 @@ bool bip_valid( return (BIP_Socket != -1); } -/** Cleanup and close out the BACnet/IP services by closing the socket. - * @ingroup DLBIP - */ -void bip_cleanup( - void) -{ - if (bip_valid()) - close(BIP_Socket); - BIP_Socket = -1; - - return; -} - void bip_set_addr( uint32_t net_address) { /* in network byte order */ @@ -181,8 +168,8 @@ int bip_send_pdu( mtu[0] = BVLL_TYPE_BACNET_IP; bip_dest.sin_family = AF_INET; function = bvlc_get_function_code(); /* What type of BVLC was it? */ - if ( (dest->net == BACNET_BROADCAST_NETWORK) || - (function == BVLC_FORWARDED_NPDU) || + if ( (dest->net == BACNET_BROADCAST_NETWORK) || + (function == BVLC_FORWARDED_NPDU) || (function == BVLC_ORIGINAL_BROADCAST_NPDU) ) { /* broadcast */ address.s_addr = BIP_Broadcast_Address.s_addr;