1+ /*
2+ * Copyright and License Notice
3+ * Chipkin Automation Systems Inc (CAS)
4+ * BACnet Stack as Source Code Product
5+ *
6+ * Simple BACnet Client Example with Business Logic
7+ */
8+
19package com .chipkin .bacnet ;
210
3- import com .sun .jna .Memory ;
4- import com .sun .jna .Pointer ;
511import java .io .BufferedReader ;
612import java .io .IOException ;
713import java .io .InputStreamReader ;
1319import java .util .Queue ;
1420import java .util .concurrent .ConcurrentLinkedQueue ;
1521
22+ import com .sun .jna .Memory ;
23+ import com .sun .jna .Pointer ;
24+
1625/**
1726 * BACnet client tutorial example.
1827 *
2231 */
2332public class SimpleBACnetClientExample {
2433
25- private static final int APPLICATION_VERSION_MAJOR = 1 ;
26- private static final int APPLICATION_VERSION_MINOR = 0 ;
27- private static final int APPLICATION_VERSION_PATCH = 0 ;
28-
2934 private static final int BACNET_UDP_PORT = 47808 ;
3035 private static final int UDP_TIMEOUT_MS = 2 ;
3136 private static final int MAX_MESSAGE_LENGTH = 2048 ;
@@ -96,7 +101,7 @@ public static void main(String[] args) {
96101
97102 private void initializeStack () throws BACnetException {
98103 System .out .println ("CAS BACnet Stack Client Example (Java) v"
99- + APPLICATION_VERSION_MAJOR + "." + APPLICATION_VERSION_MINOR + "." + APPLICATION_VERSION_PATCH );
104+ + ApplicationVersion . MAJOR + "." + ApplicationVersion . MINOR + "." + ApplicationVersion . PATCH );
100105 System .out .println ("Stack version: " + adapter .getVersionString ());
101106
102107 // Core integration point:
@@ -127,12 +132,13 @@ private void initializeStack() throws BACnetException {
127132 }
128133
129134 private void runLoop () {
135+ final long TICK_SLEEP_MS = 5 ;
130136 while (running ) {
131137 // Tick is the stack "heartbeat". Call this frequently.
132138 // It handles retries, timeouts, request tracking, and packet parsing.
133139 library .BACnetStack_Tick ();
134140 processConsoleInput ();
135- sleepQuietly (5 );
141+ sleepQuietly (TICK_SLEEP_MS );
136142 }
137143
138144 udpSocket .close ();
@@ -171,10 +177,16 @@ private void handleCommand(char input) {
171177 }
172178
173179 private void sendWhoIs () {
180+ final String BROADCAST_IP = "255.255.255.255" ;
181+ final String BROADCAST_ENDPOINT = BROADCAST_IP + ":" + BACNET_UDP_PORT ;
182+ final boolean IS_BROADCAST = true ;
183+ final short LOCAL_NETWORK = 0 ;
184+ final Pointer ROUTER_MAC = Pointer .NULL ;
185+ final byte ROUTER_MAC_LENGTH = 0 ;
174186 String target = connectionStringToHuman (targetConnectionString , targetConnectionString .length );
175187 System .out .println ("Command W: sending Who-Is (unconfirmed discovery)." );
176- System .out .println (" Destination: broadcast via " + target + " (actual UDP destination 255.255.255.255:47808 )" );
177- System .out .println (" BACnet network: 0 (local network)" );
188+ System .out .println (" Destination: broadcast via " + target + " (actual UDP destination " + BROADCAST_ENDPOINT + " )" );
189+ System .out .println (" BACnet network: " + LOCAL_NETWORK + " (local network)" );
178190
179191 Memory connection = new Memory (targetConnectionString .length );
180192 connection .write (0 , targetConnectionString , 0 , targetConnectionString .length );
@@ -183,10 +195,10 @@ private void sendWhoIs() {
183195 connection ,
184196 (byte ) targetConnectionString .length ,
185197 BACnetConstants .NETWORK_TYPE_IP ,
186- true ,
187- ( short ) 0 ,
188- Pointer . NULL ,
189- ( byte ) 0
198+ IS_BROADCAST ,
199+ LOCAL_NETWORK ,
200+ ROUTER_MAC ,
201+ ROUTER_MAC_LENGTH
190202 );
191203
192204 if (!sent ) {
@@ -195,6 +207,12 @@ private void sendWhoIs() {
195207 }
196208
197209 private void sendReadProperty () {
210+ final boolean USE_ARRAY_INDEX = false ;
211+ final int ARRAY_INDEX = 0 ;
212+ final int INVOKE_ID_LENGTH = 1 ;
213+ final short LOCAL_NETWORK = 0 ;
214+ final Pointer ROUTER_MAC = Pointer .NULL ;
215+ final byte ROUTER_MAC_LENGTH = 0 ;
198216 String target = connectionStringToHuman (targetConnectionString , targetConnectionString .length );
199217 System .out .println ("Command R: sending ReadProperty (confirmed request)." );
200218 System .out .println (" Destination: " + target + ", deviceInstance=" + targetDeviceInstance );
@@ -209,16 +227,16 @@ private void sendReadProperty() {
209227 readObjectType ,
210228 readObjectInstance ,
211229 readProperty ,
212- false ,
213- 0
230+ USE_ARRAY_INDEX ,
231+ ARRAY_INDEX
214232 );
215233
216234 if (!built ) {
217235 System .out .println ("BuildReadProperty failed." );
218236 return ;
219237 }
220238
221- Memory invokeId = new Memory (1 );
239+ Memory invokeId = new Memory (INVOKE_ID_LENGTH );
222240 Memory connection = new Memory (targetConnectionString .length );
223241 connection .write (0 , targetConnectionString , 0 , targetConnectionString .length );
224242
@@ -227,9 +245,9 @@ private void sendReadProperty() {
227245 connection ,
228246 (byte ) targetConnectionString .length ,
229247 BACnetConstants .NETWORK_TYPE_IP ,
230- ( short ) 0 ,
231- Pointer . NULL ,
232- ( byte ) 0
248+ LOCAL_NETWORK ,
249+ ROUTER_MAC ,
250+ ROUTER_MAC_LENGTH
233251 );
234252
235253 if (!sent ) {
@@ -238,44 +256,54 @@ private void sendReadProperty() {
238256 }
239257
240258 private void sendSubscribeCov () {
259+ final int INVOKE_ID_LENGTH = 1 ;
260+ final boolean CONFIRMED_NOTIFICATIONS = false ;
261+ final short LOCAL_NETWORK = 0 ;
262+ final Pointer ROUTER_MAC = Pointer .NULL ;
263+ final byte ROUTER_MAC_LENGTH = 0 ;
264+ final int ANALOG_INPUT_PROCESS_ID = 1 ;
265+ final int ANALOG_VALUE_PROCESS_ID = 2 ;
266+ final int ANALOG_INPUT_INSTANCE = 0 ;
267+ final int ANALOG_VALUE_INSTANCE = 2 ;
241268 String target = connectionStringToHuman (targetConnectionString , targetConnectionString .length );
242269 System .out .println ("Command S: sending SubscribeCOV (confirmed request)." );
243270 System .out .println (" Destination: " + target + ", deviceInstance=" + targetDeviceInstance );
244271 System .out .println (" Subscription lifetime: " + SUBSCRIPTION_LIFETIME_SECONDS + " seconds" );
245- System .out .println (" Requests: analogInput:0 (processId=1), analogValue:2 (processId=2)" );
272+ System .out .println (" Requests: analogInput:" + ANALOG_INPUT_INSTANCE + " (processId=" + ANALOG_INPUT_PROCESS_ID + "), analogValue:"
273+ + ANALOG_VALUE_INSTANCE + " (processId=" + ANALOG_VALUE_PROCESS_ID + ")" );
246274
247- Memory invokeId = new Memory (1 );
275+ Memory invokeId = new Memory (INVOKE_ID_LENGTH );
248276 Memory connection = new Memory (targetConnectionString .length );
249277 connection .write (0 , targetConnectionString , 0 , targetConnectionString .length );
250278
251279 boolean sentAi = library .BACnetStack_SendSubscribeCOV (
252280 invokeId ,
253- 1 ,
281+ ANALOG_INPUT_PROCESS_ID ,
254282 BACnetConstants .OBJECT_TYPE_ANALOG_INPUT ,
255- 0 ,
256- false ,
283+ ANALOG_INPUT_INSTANCE ,
284+ CONFIRMED_NOTIFICATIONS ,
257285 SUBSCRIPTION_LIFETIME_SECONDS ,
258286 connection ,
259287 (byte ) targetConnectionString .length ,
260288 BACnetConstants .NETWORK_TYPE_IP ,
261- ( short ) 0 ,
262- Pointer . NULL ,
263- ( byte ) 0
289+ LOCAL_NETWORK ,
290+ ROUTER_MAC ,
291+ ROUTER_MAC_LENGTH
264292 );
265293
266294 boolean sentAv = library .BACnetStack_SendSubscribeCOV (
267295 invokeId ,
268- 2 ,
296+ ANALOG_VALUE_PROCESS_ID ,
269297 BACnetConstants .OBJECT_TYPE_ANALOG_VALUE ,
270- 2 ,
271- false ,
298+ ANALOG_VALUE_INSTANCE ,
299+ CONFIRMED_NOTIFICATIONS ,
272300 SUBSCRIPTION_LIFETIME_SECONDS ,
273301 connection ,
274302 (byte ) targetConnectionString .length ,
275303 BACnetConstants .NETWORK_TYPE_IP ,
276- ( short ) 0 ,
277- Pointer . NULL ,
278- ( byte ) 0
304+ LOCAL_NETWORK ,
305+ ROUTER_MAC ,
306+ ROUTER_MAC_LENGTH
279307 );
280308
281309 if (!sentAi || !sentAv ) {
@@ -333,6 +361,7 @@ private short handleSendMessage(Pointer message,
333361 byte connectionStringLength ,
334362 byte networkType ,
335363 boolean broadcast ) {
364+ final int MIN_CONNECTION_STRING_LENGTH = 6 ;
336365 if (messageLength <= 0 ) {
337366 return 0 ;
338367 }
@@ -343,7 +372,7 @@ private short handleSendMessage(Pointer message,
343372 }
344373
345374 int connLength = Byte .toUnsignedInt (connectionStringLength );
346- if (connLength < 6 ) {
375+ if (connLength < MIN_CONNECTION_STRING_LENGTH ) {
347376 System .out .println ("Cannot send, connection string too short: " + connLength );
348377 return 0 ;
349378 }
@@ -464,33 +493,41 @@ private void parseArguments(String[] args) {
464493 }
465494
466495 private void buildTargetConnectionString (String ip , int port ) {
496+ final int IPV4_OCTET_COUNT = 4 ;
497+ final int PORT_HIGH_INDEX = 4 ;
498+ final int PORT_LOW_INDEX = 5 ;
467499 String [] parts = ip .split ("\\ ." );
468- if (parts .length != 4 ) {
500+ if (parts .length != IPV4_OCTET_COUNT ) {
469501 throw new IllegalArgumentException ("Invalid IPv4 address: " + ip );
470502 }
471503
472- for (int i = 0 ; i < 4 ; i ++) {
504+ for (int i = 0 ; i < IPV4_OCTET_COUNT ; i ++) {
473505 targetConnectionString [i ] = (byte ) parseIntOrDefault (parts [i ], 0 );
474506 }
475- targetConnectionString [4 ] = (byte ) ((port >> 8 ) & 0xFF );
476- targetConnectionString [5 ] = (byte ) (port & 0xFF );
507+ targetConnectionString [PORT_HIGH_INDEX ] = (byte ) ((port >> 8 ) & 0xFF );
508+ targetConnectionString [PORT_LOW_INDEX ] = (byte ) (port & 0xFF );
477509 }
478510
479511 private byte [] toConnectionString (InetAddress address , int port ) {
480- byte [] out = new byte [6 ];
512+ final int IPV4_OCTET_COUNT = 4 ;
513+ final int CONNECTION_STRING_LENGTH = 6 ;
514+ final int PORT_HIGH_INDEX = 4 ;
515+ final int PORT_LOW_INDEX = 5 ;
516+ byte [] out = new byte [CONNECTION_STRING_LENGTH ];
481517 byte [] ipBytes = address .getAddress ();
482- if (ipBytes .length != 4 ) {
518+ if (ipBytes .length != IPV4_OCTET_COUNT ) {
483519 throw new IllegalStateException ("Expected IPv4 address, got length=" + ipBytes .length );
484520 }
485521
486- System .arraycopy (ipBytes , 0 , out , 0 , 4 );
487- out [4 ] = (byte ) ((port >> 8 ) & 0xFF );
488- out [5 ] = (byte ) (port & 0xFF );
522+ System .arraycopy (ipBytes , 0 , out , 0 , IPV4_OCTET_COUNT );
523+ out [PORT_HIGH_INDEX ] = (byte ) ((port >> 8 ) & 0xFF );
524+ out [PORT_LOW_INDEX ] = (byte ) (port & 0xFF );
489525 return out ;
490526 }
491527
492528 private static String connectionStringToHuman (byte [] connectionString , int length ) {
493- if (connectionString == null || length < 6 ) {
529+ final int CONNECTION_STRING_LENGTH = 6 ;
530+ if (connectionString == null || length < CONNECTION_STRING_LENGTH ) {
494531 return "invalid-connection-string" ;
495532 }
496533
0 commit comments