@@ -61,7 +61,7 @@ uint8_t invokeId;
61
61
62
62
// Constants
63
63
// =======================================
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.
65
65
const uint32_t MAX_XML_RENDER_BUFFER_LENGTH = 1024 * 20 ;
66
66
67
67
// Settings
@@ -71,6 +71,7 @@ const uint32_t SETTING_CLIENT_DEVICE_INSTANCE = 389002;
71
71
const uint16_t SETTING_DOWNSTREAM_DEVICE_PORT = SETTING_BACNET_IP_PORT;
72
72
const uint32_t SETTING_DOWNSTREAM_DEVICE_INSTANCE = 389999 ;
73
73
const std::string SETTING_DEFAULT_DOWNSTREAM_DEVICE_IP_ADDRESS = " 192.168.2.217" ;
74
+ const std::string SETTING_DEFAULT_DEVICE_PASSWORD = " 12345" ;
74
75
75
76
// Downstream IP Initialization
76
77
// =======================================
@@ -79,7 +80,7 @@ std::string downstream_Device_ip_address;
79
80
80
81
// Callback Functions to Register to the DLL
81
82
// 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);
83
84
uint16_t CallbackSendMessage (const uint8_t * message, const uint16_t messageLength, const uint8_t * connectionString, const uint8_t connectionStringLength, const uint8_t networkType, bool broadcast);
84
85
85
86
// System Functions
@@ -126,7 +127,11 @@ void ExampleWhoIs();
126
127
void ExampleReadProperty ();
127
128
void ExampleWriteProperty ();
128
129
void ExampleSubscribeCOV ();
130
+ void ExampleSubscribeCOVProperty ();
129
131
void ExampleConfirmedTextMessage ();
132
+ void ExampleTimeSynchronizationMessage ();
133
+ void ExampleReinitializeDevice ();
134
+ void ExampleDeviceCommunicationControl (bool enable);
130
135
131
136
int main (int argc, char ** argv )
132
137
{
@@ -242,7 +247,7 @@ int main(int argc, char ** argv )
242
247
std::cout << " FYI: Entering main loop..." << std::endl;
243
248
for (;;) {
244
249
// Call the DLLs loop function which checks for messages and processes them.
245
- fpLoop ();
250
+ fpTick ();
246
251
247
252
// Handle any user input.
248
253
if (!DoUserInput ()) {
@@ -287,14 +292,35 @@ bool DoUserInput()
287
292
ExampleWriteProperty ();
288
293
break ;
289
294
}
290
- case ' c ' : {
295
+ case ' s ' : {
291
296
ExampleSubscribeCOV ();
292
297
break ;
293
298
}
294
- case ' t' : {
299
+ case ' p' : {
300
+ ExampleSubscribeCOVProperty ();
301
+ break ;
302
+ }
303
+ case ' m' : {
295
304
ExampleConfirmedTextMessage ();
296
305
break ;
297
306
}
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' :
298
324
default : {
299
325
// Print the Help
300
326
std::cout << std::endl << std::endl;
@@ -305,12 +331,18 @@ bool DoUserInput()
305
331
std::cout << " Example: BACnetClient 192.168.1.126" << std::endl << std::endl;
306
332
307
333
std::cout << " Help: " << std::endl;
308
- std::cout << " - Q - Quit" << std::endl;
309
334
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;
314
346
std::cout << std::endl;
315
347
break ;
316
348
}
@@ -325,7 +357,7 @@ bool DoUserInput()
325
357
void WaitForResponse (unsigned int timeout /* =3*/ ) {
326
358
time_t expireTime = time (0 ) + timeout;
327
359
while (time (0 ) < expireTime) {
328
- fpLoop ();
360
+ fpTick ();
329
361
}
330
362
}
331
363
@@ -437,7 +469,7 @@ void ExampleSubscribeCOV() {
437
469
438
470
// Subscribe to the analog input and analog value objects in the server example
439
471
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;
441
473
fpSendSubscribeCOV (&invokeId, analogInputProcessIdentifier, CASBACnetStackExampleConstants::OBJECT_TYPE_ANALOG_INPUT, 0 , false , timeToLive, downstreamConnectionString, 6 , 0 , 0 , NULL , 0 );
442
474
443
475
WaitForResponse ();
@@ -448,6 +480,18 @@ void ExampleSubscribeCOV() {
448
480
WaitForResponse ();
449
481
}
450
482
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
+
451
495
void ExampleConfirmedTextMessage () {
452
496
// Text message settings
453
497
bool useMessageClass = true ; // Enable or disable message class property
@@ -464,21 +508,74 @@ void ExampleConfirmedTextMessage() {
464
508
WaitForResponse ();
465
509
}
466
510
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
+
467
564
468
565
// ================================================================================================
469
566
// Callbacks
470
567
// ================================================================================================
471
568
472
569
473
570
// 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)
475
572
{
476
573
// Check parameters
477
574
if (message == NULL || maxMessageLength == 0 ) {
478
575
std::cerr << " Invalid input buffer" << std::endl;
479
576
return 0 ;
480
577
}
481
- if (receivedConnectionString == NULL || maxConnectionStringLength == 0 ) {
578
+ if (sourceConnectionString == NULL || maxConnectionStringLength == 0 ) {
482
579
std::cerr << " Invalid connection string buffer" << std::endl;
483
580
return 0 ;
484
581
}
@@ -497,14 +594,14 @@ uint16_t CallbackReceiveMessage(uint8_t* message, const uint16_t maxMessageLengt
497
594
std::cout << " FYI: Received message from [" << ipAddress << " :" << port << " ], length [" << bytesRead << " ]" << std::endl;
498
595
499
596
// Convert the IP Address to the connection string
500
- if (!ChipkinCommon::ChipkinConvert::IPAddressToBytes (ipAddress, receivedConnectionString , maxConnectionStringLength)) {
597
+ if (!ChipkinCommon::ChipkinConvert::IPAddressToBytes (ipAddress, sourceConnectionString , maxConnectionStringLength)) {
501
598
std::cerr << " Failed to convert the ip address into a connectionString" << std::endl;
502
599
return 0 ;
503
600
}
504
- receivedConnectionString [4 ] = port / 256 ;
505
- receivedConnectionString [5 ] = port % 256 ;
601
+ sourceConnectionString [4 ] = port / 256 ;
602
+ sourceConnectionString [5 ] = port % 256 ;
506
603
507
- *receivedConnectionStringLength = 6 ;
604
+ *sourceConnectionStringLength = 6 ;
508
605
*networkType = CASBACnetStackExampleConstants::NETWORK_TYPE_IP;
509
606
510
607
// Process the message as XML
@@ -568,7 +665,7 @@ uint16_t CallbackSendMessage(const uint8_t* message, const uint16_t messageLengt
568
665
569
666
// Get the XML rendered version of the just sent message
570
667
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 ) {
572
669
std::cout << xmlRenderBuffer << std::endl << std::endl;
573
670
memset (xmlRenderBuffer, 0 , MAX_XML_RENDER_BUFFER_LENGTH);
574
671
}
0 commit comments