@@ -61,7 +61,7 @@ uint8_t invokeId;
6161
6262// Constants
6363// =======================================
64- const std::string APPLICATION_VERSION = " 0 .0.9 " ; // See CHANGELOG.md for a full list of changes.
64+ const std::string APPLICATION_VERSION = " 1 .0.0 " ; // See CHANGELOG.md for a full list of changes.
6565const uint32_t MAX_XML_RENDER_BUFFER_LENGTH = 1024 * 20 ;
6666
6767// Settings
@@ -71,6 +71,7 @@ const uint32_t SETTING_CLIENT_DEVICE_INSTANCE = 389002;
7171const uint16_t SETTING_DOWNSTREAM_DEVICE_PORT = SETTING_BACNET_IP_PORT;
7272const uint32_t SETTING_DOWNSTREAM_DEVICE_INSTANCE = 389999 ;
7373const std::string SETTING_DEFAULT_DOWNSTREAM_DEVICE_IP_ADDRESS = " 192.168.2.217" ;
74+ const std::string SETTING_DEFAULT_DEVICE_PASSWORD = " 12345" ;
7475
7576// Downstream IP Initialization
7677// =======================================
@@ -79,7 +80,7 @@ std::string downstream_Device_ip_address;
7980
8081// Callback Functions to Register to the DLL
8182// Message Functions
82- uint16_t CallbackReceiveMessage (uint8_t * message, const uint16_t maxMessageLength, uint8_t * receivedConnectionString, const uint8_t maxConnectionStringLength , uint8_t * receivedConnectionStringLength , uint8_t * networkType);
83+ uint16_t CallbackReceiveMessage (uint8_t * message, const uint16_t maxMessageLength, uint8_t * sourceConnectionString, uint8_t * sourceConnectionStringLength, uint8_t * destinationConnectionString , uint8_t * destinationConnectionStringLength, const uint8_t maxConnectionStringLength , uint8_t * networkType);
8384uint16_t CallbackSendMessage (const uint8_t * message, const uint16_t messageLength, const uint8_t * connectionString, const uint8_t connectionStringLength, const uint8_t networkType, bool broadcast);
8485
8586// System Functions
@@ -126,7 +127,11 @@ void ExampleWhoIs();
126127void ExampleReadProperty ();
127128void ExampleWriteProperty ();
128129void ExampleSubscribeCOV ();
130+ void ExampleSubscribeCOVProperty ();
129131void ExampleConfirmedTextMessage ();
132+ void ExampleTimeSynchronizationMessage ();
133+ void ExampleReinitializeDevice ();
134+ void ExampleDeviceCommunicationControl (bool enable);
130135
131136int main (int argc, char ** argv )
132137{
@@ -242,7 +247,7 @@ int main(int argc, char ** argv )
242247 std::cout << " FYI: Entering main loop..." << std::endl;
243248 for (;;) {
244249 // Call the DLLs loop function which checks for messages and processes them.
245- fpLoop ();
250+ fpTick ();
246251
247252 // Handle any user input.
248253 if (!DoUserInput ()) {
@@ -287,14 +292,35 @@ bool DoUserInput()
287292 ExampleWriteProperty ();
288293 break ;
289294 }
290- case ' c ' : {
295+ case ' s ' : {
291296 ExampleSubscribeCOV ();
292297 break ;
293298 }
294- case ' t' : {
299+ case ' p' : {
300+ ExampleSubscribeCOVProperty ();
301+ break ;
302+ }
303+ case ' m' : {
295304 ExampleConfirmedTextMessage ();
296305 break ;
297306 }
307+ case ' t' : {
308+ ExampleTimeSynchronizationMessage ();
309+ break ;
310+ }
311+ case ' i' : {
312+ ExampleReinitializeDevice ();
313+ break ;
314+ }
315+ case ' d' : {
316+ ExampleDeviceCommunicationControl (false );
317+ break ;
318+ }
319+ case ' e' : {
320+ ExampleDeviceCommunicationControl (true );
321+ break ;
322+ }
323+ case ' h' :
298324 default : {
299325 // Print the Help
300326 std::cout << std::endl << std::endl;
@@ -305,12 +331,18 @@ bool DoUserInput()
305331 std::cout << " Example: BACnetClient 192.168.1.126" << std::endl << std::endl;
306332
307333 std::cout << " Help: " << std::endl;
308- std::cout << " - Q - Quit" << std::endl;
309334 std::cout << " - W - Send WhoIs message" << std::endl;
310- std::cout << " - R - Send Read property messages" << std::endl;
311- std::cout << " - U - Send Write property messages" << std::endl;
312- std::cout << " - C - Send Subscribe COV Request" << std::endl;
313- std::cout << " - T - Send Confirmed Text Message Request" << std::endl;
335+ std::cout << " - R - Send ReadProperty messages" << std::endl;
336+ std::cout << " - U - Send WriteProperty messages" << std::endl;
337+ std::cout << " - S - Send SubscribeCOV Request" << std::endl;
338+ std::cout << " - P - Send SubscribeCOVProperty Request" << std::endl;
339+ std::cout << " - M - Send ConfirmedTextMessage Request" << std::endl;
340+ std::cout << " - T - Send TimeSynchronization Request" << std::endl;
341+ std::cout << " - R - Send ReinitializedDevice Request" << std::endl;
342+ std::cout << " - D - Send DeviceCommunicationControl Request to Disable" << std::endl;
343+ std::cout << " - E - Send DeviceCommunicationControl Request to Enable" << std::endl;
344+ std::cout << " - H - Display Help information" << std::endl;
345+ std::cout << " - Q - Quit" << std::endl;
314346 std::cout << std::endl;
315347 break ;
316348 }
@@ -325,7 +357,7 @@ bool DoUserInput()
325357void WaitForResponse (unsigned int timeout /* =3*/ ) {
326358 time_t expireTime = time (0 ) + timeout;
327359 while (time (0 ) < expireTime) {
328- fpLoop ();
360+ fpTick ();
329361 }
330362}
331363
@@ -437,7 +469,7 @@ void ExampleSubscribeCOV() {
437469
438470 // Subscribe to the analog input and analog value objects in the server example
439471
440- std::cout << " Sending Subscribe COV Request. Analog Input, INSTANCE=[0], timeToLive = " << timeToLive << " , processIdentifier = " << analogValueProcessIdentifier << std::endl;
472+ std::cout << " Sending Subscribe COV Request. Analog Input, INSTANCE=[0], timeToLive = " << timeToLive << " , processIdentifier = " << analogInputProcessIdentifier << std::endl;
441473 fpSendSubscribeCOV (&invokeId, analogInputProcessIdentifier, CASBACnetStackExampleConstants::OBJECT_TYPE_ANALOG_INPUT, 0 , false , timeToLive, downstreamConnectionString, 6 , 0 , 0 , NULL , 0 );
442474
443475 WaitForResponse ();
@@ -448,6 +480,18 @@ void ExampleSubscribeCOV() {
448480 WaitForResponse ();
449481}
450482
483+ void ExampleSubscribeCOVProperty () {
484+ const uint16_t timeToLive = 60 * 5 ; // 5 Min subscription time
485+
486+ // Local process identifier, must be unique for each subscribe COV request
487+ const uint16_t analogValueProcessIdentifier = 0 ;
488+
489+ // Subscribe to the analog input and analog value objects in the server example
490+
491+ std::cout << " Sending Subscribe COV Property Request. Analog Value, INSTANCE=[2], timeToLive = " << timeToLive << " , processIdentifier = " << analogValueProcessIdentifier << std::endl;
492+ fpSendSubscribeCOVProperty (&invokeId, analogValueProcessIdentifier, CASBACnetStackExampleConstants::OBJECT_TYPE_ANALOG_VALUE, 2 , CASBACnetStackExampleConstants::PROPERTY_IDENTIFIER_PRESENT_VALUE, false , 0 , true , 5 .0f , false , timeToLive, downstreamConnectionString, 6 , 0 , 0 , NULL , 0 );
493+ }
494+
451495void ExampleConfirmedTextMessage () {
452496 // Text message settings
453497 bool useMessageClass = true ; // Enable or disable message class property
@@ -464,21 +508,74 @@ void ExampleConfirmedTextMessage() {
464508 WaitForResponse ();
465509}
466510
511+ void ExampleTimeSynchronizationMessage () {
512+ // Time Synchronization Settings
513+ uint8_t year = 2024 - 1900 ;
514+ uint8_t month = 8 ;
515+ uint8_t day = 15 ;
516+ uint8_t weekday = 3 ;
517+ uint8_t hour = 8 ;
518+ uint8_t minute = 8 ;
519+ uint8_t seconds = 8 ;
520+ uint8_t hundrethSeconds = 0 ;
521+
522+ // Send TimeSynchronization request
523+ // C++ server example configured to handle
524+ std::cout << " Sending TimeSynchronization Message" ;
525+ fpSendTimeSynchronization (year, month, day, weekday, hour, minute, seconds, hundrethSeconds, downstreamConnectionString, 6 , 0 , false , 0 , NULL , 0 );
526+
527+ WaitForResponse ();
528+ // Note: TimeSynchronization is an unconfirmed request, which means the downstream device will not response.
529+ // The WaitForResponse is called here just to wait for some cycles before continuing.
530+
531+ // Send UtcTimeSynchronization request
532+ // C++ server example configured to handle
533+ std::cout << " Sending UTCTimeSynchronization Message" ;
534+ fpSendUTCTimeSynchronization (year, month, day, weekday, hour, minute, seconds, hundrethSeconds, downstreamConnectionString, 6 , 0 , false , 0 , NULL , 0 );
535+
536+ WaitForResponse ();
537+ }
538+
539+ void ExampleReinitializeDevice () {
540+ // ReinitializeDevice Settings
541+ uint8_t reinitializedState = CASBACnetStackExampleConstants::REINITIALIZED_STATE_ACTIVATE_CHANGES;
542+
543+ // Send ReinitializeDevice request
544+ // C++ server example configured to handle
545+ std::cout << " Sending ReinitializeDevice Message to activate changes" ;
546+ fpSendReinitializeDevice (&invokeId, reinitializedState, SETTING_DEFAULT_DEVICE_PASSWORD.c_str (), SETTING_DEFAULT_DEVICE_PASSWORD.length (), downstreamConnectionString, 6 , 0 , 0 , NULL , 0 );
547+ }
548+
549+ void ExampleDeviceCommunicationControl (bool enable) {
550+ if (enable) {
551+ // Send DeviceCommunicationControl request
552+ // C++ server example configured to handle
553+ std::cout << " Sending DeviceCommunicationControl Message to enable BACnet communication" ;
554+ fpSendDeviceCommunicationControl (&invokeId, CASBACnetStackExampleConstants::ENABLEDISABLE_ENABLE, false , 0 , SETTING_DEFAULT_DEVICE_PASSWORD.c_str (), SETTING_DEFAULT_DEVICE_PASSWORD.length (), downstreamConnectionString, 6 , 0 , 0 , NULL , 0 );
555+ }
556+ else {
557+ // Send DeviceCommunicationControl request
558+ // C++ server example configured to handle
559+ std::cout << " Sending DeviceCommunicationControl Message to disable BACnet communication" ;
560+ fpSendDeviceCommunicationControl (&invokeId, CASBACnetStackExampleConstants::ENABLEDISABLE_DISABLE, false , 0 , SETTING_DEFAULT_DEVICE_PASSWORD.c_str (), SETTING_DEFAULT_DEVICE_PASSWORD.length (), downstreamConnectionString, 6 , 0 , 0 , NULL , 0 );
561+ }
562+ }
563+
467564
468565// ================================================================================================
469566// Callbacks
470567// ================================================================================================
471568
472569
473570// Callback used by the BACnet Stack to check if there is a message to process
474- uint16_t CallbackReceiveMessage (uint8_t * message, const uint16_t maxMessageLength, uint8_t * receivedConnectionString, const uint8_t maxConnectionStringLength , uint8_t * receivedConnectionStringLength , uint8_t * networkType)
571+ uint16_t CallbackReceiveMessage (uint8_t * message, const uint16_t maxMessageLength, uint8_t * sourceConnectionString, uint8_t * sourceConnectionStringLength, uint8_t * destinationConnectionString , uint8_t * destinationConnectionStringLength, const uint8_t maxConnectionStringLength , uint8_t * networkType)
475572{
476573 // Check parameters
477574 if (message == NULL || maxMessageLength == 0 ) {
478575 std::cerr << " Invalid input buffer" << std::endl;
479576 return 0 ;
480577 }
481- if (receivedConnectionString == NULL || maxConnectionStringLength == 0 ) {
578+ if (sourceConnectionString == NULL || maxConnectionStringLength == 0 ) {
482579 std::cerr << " Invalid connection string buffer" << std::endl;
483580 return 0 ;
484581 }
@@ -497,14 +594,14 @@ uint16_t CallbackReceiveMessage(uint8_t* message, const uint16_t maxMessageLengt
497594 std::cout << " FYI: Received message from [" << ipAddress << " :" << port << " ], length [" << bytesRead << " ]" << std::endl;
498595
499596 // Convert the IP Address to the connection string
500- if (!ChipkinCommon::ChipkinConvert::IPAddressToBytes (ipAddress, receivedConnectionString , maxConnectionStringLength)) {
597+ if (!ChipkinCommon::ChipkinConvert::IPAddressToBytes (ipAddress, sourceConnectionString , maxConnectionStringLength)) {
501598 std::cerr << " Failed to convert the ip address into a connectionString" << std::endl;
502599 return 0 ;
503600 }
504- receivedConnectionString [4 ] = port / 256 ;
505- receivedConnectionString [5 ] = port % 256 ;
601+ sourceConnectionString [4 ] = port / 256 ;
602+ sourceConnectionString [5 ] = port % 256 ;
506603
507- *receivedConnectionStringLength = 6 ;
604+ *sourceConnectionStringLength = 6 ;
508605 *networkType = CASBACnetStackExampleConstants::NETWORK_TYPE_IP;
509606
510607 // Process the message as XML
@@ -568,7 +665,7 @@ uint16_t CallbackSendMessage(const uint8_t* message, const uint16_t messageLengt
568665
569666 // Get the XML rendered version of the just sent message
570667 static char xmlRenderBuffer[MAX_XML_RENDER_BUFFER_LENGTH];
571- if (fpDecodeAsXML ((char *)message, messageLength, xmlRenderBuffer, MAX_XML_RENDER_BUFFER_LENGTH, networkType ) > 0 ) {
668+ if (fpDecodeAsXML ((char *)message, messageLength, xmlRenderBuffer, MAX_XML_RENDER_BUFFER_LENGTH, CASBACnetStackExampleConstants::NETWORK_TYPE_IP ) > 0 ) {
572669 std::cout << xmlRenderBuffer << std::endl << std::endl;
573670 memset (xmlRenderBuffer, 0 , MAX_XML_RENDER_BUFFER_LENGTH);
574671 }
0 commit comments