summaryrefslogtreecommitdiff
path: root/peripheral/libupm/src/bacnetmstp/bacnetutil.hpp
blob: 463d1d8946fb8496d10dea4cb51e245709f469ef (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
/*
 * Author: Jon Trulson <jtrulson@ics.com>
 * Copyright (c) 2016 Intel Corporation.
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublicense, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */
#pragma once

#include <string>
#include <map>
#include <vector>

#include "bacnetmstp.hpp"

namespace upm {

  /**
   * @library bacnetmstp
   * @comname UPM Utility API for BACnet
   * @con uart
   *
   * @brief UPM Utility API for BACnet
   *
   * This class implements some common access functions that are
   * useful to any driver making use of the bacnetmstp driver.
   *
   * It provides some basic functionality for reading and writing a
   * proprty (with and without relability checking) as well as access
   * to error conditions.  It is intended to be inherited by your
   * driver class.
   */

  class BACNETUTIL {
  public:

    /**
     * BACNETUTIL constructor
     *
     */
    BACNETUTIL(uint32_t targetDeviceObjectID);

    /**
     * BACNETUTIL Destructor
     */
    virtual ~BACNETUTIL();

    /**
     * This function initializes the underlying BACNETMSTP Master
     * singleton in the event it has not already been initialized.  If
     * the BACNETMSTP Master singleton has already been initialized,
     * then this call will be ignored.
     *
     * @param port The serial port that the RS-485 interface is
     * connected to.
     * @param baudRate The baudrate of the RS-485 interface.  All
     * devices on a BACnet RS-485 bus must run at the same baudrate.
     * Valid values are 9600, 19200, 38400, 57600, 76800, and 115200.
     * @param deviceInstanceNumber This is the unique Device Object
     * Instance number that will be used for our BACnet Master in
     * order to communicate over the BACnet interface.  This number
     * must be between 1-4194302 and must be unique on the BACnet
     * network.
     * @param macAddr This is the MAC address of our BACnet Master.
     * It must be unique on the BACnet segment, and must be between
     * 1-127.
     * @param maxMaster This specifies to our Master the maximum MAC
     * address used by any other Masters on the BACnet network.  This
     * must be between 1-127, the default is 127.  Do not change this
     * unless you know what you are doing or you could introduce
     * token passing errors on the BACnet network.
     * @param maxInfoFrames This number specifies the maximum number
     * of transmissions (like requests for data) our Master is allowed
     * to make before passing the token to the next Master.  The
     * default is 1.
     */
    virtual void initMaster(std::string port, int baudRate,
                            int deviceInstanceNumber,
                            int macAddr, int maxMaster=DEFAULT_MAX_MASTER,
                            int maxInfoFrames=1);

    /**
     * Enable some debugging output in this module as well as the
     * BACNETMSTP module.  Debugging is disabled by default.
     *
     * @param enable true to enable, false to disable.
     */
    virtual void setDebug(bool enable);

    /**
     * Retrieve the Present_Value property of an Analog Value object.
     * If checkReliability() has been enabled, then the Reliability
     * property of the object will be retrieved first.  If the
     * Reliability property is anything other than
     * RELIABILITY_NO_FAULT_DETECTED, then the method will throw.
     * Reliability checking is disabled by default for performance
     * reasons.
     *
     * @param objInstance The Analog Value Object instance.
     * @return The floating point value requested.
     */
    virtual float getAnalogValue(uint32_t objInstance);

    /**
     * Set the Present_Value property of an Analog Value object.  This
     * method will throw on an error.
     *
     * @param objInstance The Analog Value Object instance.
     * @param value The data value to write.
     */
    virtual void setAnalogValue(uint32_t objInstance,
                                float value);

    /**
     * Retrieve the Present_Value property of an Analog Input object.
     * If checkReliability() has been enabled, then the Reliability
     * property of the object will be retrieved first.  If the
     * Reliability property is anything other than
     * RELIABILITY_NO_FAULT_DETECTED, then the method will throw.
     * Reliability checking is disabled by default for performance
     * reasons.
     *
     * @param objInstance The Analog Input Object instance.
     * @return the floating point value requested.
     */
    virtual float getAnalogInput(uint32_t objInstance);

    /**
     * Query an Analog Value object for the unit code, translate it
     * into a string and cache the result for future use.  Return the
     * BACnet text for the Unit enumeration.  Unit enumerations are
     * things like 'kilowatt-hours', 'volts', etc.  For Objects which
     * do not have a Units property defined for them, or for which
     * Units has no meaning, 'no-units' will typically be returned and
     * cached for the object.
     *
     * @param objInstance The Analog Value Object instance.
     * @return A string representing the Object's Unit property.
     */
    virtual std::string getAnalogValueUnits(uint32_t objInstance);

    /**
     * Query an Analog Input object for the unit code, translate it
     * into a string and cache the result for future use.  Return the
     * BACnet text for the Unit enumeration.  Unit enumerations are
     * things like 'kilowatt-hours', 'volts', etc.  For Objects which
     * do not have a Units property defined for them, or for which
     * Units has no meaning, 'no-units' will typically be returned and
     * cached for the object.
     *
     * @param objInstance The Analog Input Object instance.
     * @return A string representing the Object's Unit property.
     */
    virtual std::string getAnalogInputUnits(uint32_t objInstance);

    /**
     * Retrieve the Present_Value property of a Binary Input object.
     * If checkReliability() has been enabled, then the Reliability
     * property of the object will be retrieved first.  If the
     * Reliability property is anything other than
     * RELIABILITY_NO_FAULT_DETECTED, then the method will throw.
     * Reliability checking is disabled by default for performance
     * reasons.
     *
     * @param objInstance The Object Instance number to query
     * @return the boolean point value requested
     */
    virtual bool getBinaryInput(uint32_t objInstance);

    /**
     * Lookup (retrieve if necessary) the Inactive_Text and
     * Active_Text properties of a Binary Input object.  These text
     * properties are optional and can provide a string representing a
     * given state (true/false) that can be more informational than
     * just the boolean value the object represents.  This is useful
     * in applications that display this data to a user for example.
     * If this text is not present in the object (as it is not
     * required), then a string representation of the value will be
     * returned instead ("active" and "inactive").
     *
     * @param objInstance The Object Instance number of the object
     * @param value The value you want to lookup the text
     * representation for.
     * @return The string representing the value.
     */
    virtual std::string lookupBinaryInputText(uint32_t objInstance, bool value);

    /**
     * Return a string representation of the Present_Value property of
     * a BinaryInput object.  This method just calls getBinaryInput()
     * on the object, uses lookupBinaryInputText() to lookup the
     * corresponding text value, and returns the result.
     *
     * @param objInstance The Object Instance number of the object.
     * @return The string representing the value.
     */
    virtual std::string getBinaryInputText(uint32_t objInstance);

    /**
     * Retrieve the Present_Value property of a Binary Value object.
     * If checkReliability() has been enabled, then the Reliability
     * property of the object will be retrieved first.  If the
     * Reliability property is anything other than
     * RELIABILITY_NO_FAULT_DETECTED, then the method will throw.
     * Reliability checking is disabled by default for performance
     * reasons.
     *
     * @param objInstance The Object Instance number to query
     * @return the boolean point value requested
     */
    virtual bool getBinaryValue(uint32_t objInstance);

    /**
     * Set the Present_Value property of a Binary Value object.  This
     * method will throw on an error.
     *
     * @param objInstance The Analog Value Object instance.
     * @param value The data value to write
     */
    virtual void setBinaryValue(uint32_t objInstance,
                                bool value);

    /**
     * Lookup (retrieve if necessary) the Inactive_Text and
     * Active_Text properties of a Binary Value object.  These text
     * properties are optional and can provide a string representing a
     * given state (true/false) that can be more informational than
     * just the boolean value the object represents.  This is useful
     * in applications that display this data to a user for example.
     * If this text is not present in the object (as it is not
     * required), then a string representation of the value will be
     * returned instead ("active" and "inactive").
     *
     * @param objInstance The Object Instance number of the object.
     * @param value The value you want to lookup the text
     * representation for.
     * @return The string representing the value.
     */
    virtual std::string lookupBinaryValueText(uint32_t objInstance, bool value);

    /**
     * Return a string representation of the Present_Value property of
     * a Binary Value object.  This method just calls getBinaryValue()
     * on the object, uses lookupBinaryValueText() to lookup the
     * corresponding text value, and returns the result.
     *
     * @param objInstance The Object Instance number of the object.
     * @return The string representing the value.
     */
    virtual std::string getBinaryValueText(uint32_t objInstance);

    /**
     * Retrieve the Present_Value property of a Multi State Value
     * object.  If checkReliability() has been enabled, then the
     * Reliability property of the object will be retrieved first.  If
     * the Reliability property is anything other than
     * RELIABILITY_NO_FAULT_DETECTED, then the method will throw.
     * Reliability checking is disabled by default for performance
     * reasons.
     *
     * @param objInstance The Object Instance number to query.
     * @return The Present_Value property of the object.
     */
    virtual unsigned int getMultiStateValue(uint32_t objInstance);

    /**
     * Lookup (retrieve if necessary) the State_Text strings
     * corresponding to the supplied value of a MultiStateValue
     * object.  State_Text is an optional property that can provide
     * strings representing a given state that can be more
     * informational than just the unsigned integer the object
     * represents.  This is useful in applications that display this
     * data to a user for example.  If this text is not present in the
     * object (as it is not required), then a string representation of
     * the integer value will be returned instead.
     *
     * @param objInstance The Object Instance number of the object.
     * @param value The value you want to lookup the text
     * representation for.
     * @return The string representing the value.
     */
    virtual std::string lookupMultiStateValueText(uint32_t objInstance,
                                                  unsigned int value);

    /**
     * Return a string representation of the Present_Value property of
     * a MultiStateValue object.  This method just calls
     * getMultiStateValue() on the object, uses
     * lookupMultiStateValueText() to lookup the corresponding
     * State_Text value, and returns the result.
     *
     * @param objInstance The Object Instance number of the object.
     * @return The string representing the value.
     */
    virtual std::string getMultiStateValueText(uint32_t objInstance);

    /**
     * Return the maximum legal value of a Multi State Value Object.
     * The value represents the highest value the Present_Value
     * porperty of the object will allow.
     *
     * @param objInstance The Object Instance number of the object.
     * @return The highest Present_Value the object supports.
     */
    virtual unsigned int getMultiStateValueMaxStates(uint32_t objInstance);

    /**
     * Set the Present_Value property of a Multi State Value object.
     * The value provided must not be 0, and must not exceed the
     * object's Number_Of_States property. Use
     * getMultiStateValueMaxStates() to determine the maximum value
     * the object supports. This method will throw on an error.
     *
     * @param objInstance The MultiStateValue Object instance.
     * @param value The data value to write.
     */
    virtual void setMultiStateValue(uint32_t objInstance,
                                    unsigned int value);

    /**
     * Enable or disable reliability checking.  When retrieving data,
     * the Present_Value property is returned.  There is also an
     * optional property called Reliability that can be checked to
     * ensure that the Present_Value property is currently valid.
     *
     * Enabling Reliability Checking has the data retrieval functions
     * check for a RELIABILITY_NO_FAULT_DETECTED value for the
     * Reliability property before querying the Present_Value
     * property.  If anything other than RELIABILITY_NO_FAULT_DETECTED
     * is set, then the method will throw.
     *
     * This checking is disabled by default since it will double the
     * number of queries needed to retrieve a given value.  In
     * addition, since it is an optional property, calling it for an
     * object that does not support it will also throw.  However, if
     * you need to ensure that the values returned are always
     * completely valid as determined by the device firmware, and the
     * objects you are querying support the reliability property, you
     * can enable this.
     *
     * @param enable true to check Reliability before returning a
     * value, false otherwise.
     */
    virtual void checkReliability(bool enable)
    {
      m_checkReliability = enable;
    };

    /**
     * Query the Device Object of the device and return it's
     * Description property.  This typically contains information like
     * the Vendor, model and serial number of a device.
     *
     * @return A string containing the Device Object's Description property.
     */
    virtual std::string getDeviceDescription();

    /**
     * Query the Device Object of the device and return it's Location
     * property.  This typically contains a string indication of a
     * customer specific value.  Use setLocation() to change.
     *
     * @return A string containing the Device Object's Location property.
     */
    virtual std::string getDeviceLocation();

    /**
     * Set the Device Object's Location property.  This must be a
     * string containing no more than 63 characters.  Not all devices
     * allow setting the location.
     *
     * @param location The new location to set, if supported.
     * @return true if the operation succeeded, otherwise false.
     */
    virtual bool setDeviceLocation(std::string location);

    /**
     * Query the Device Object of the device and return it's Name
     * property.  This should contain a unique string value.  Use
     * setName() to change.  Note, according to the spec, the Device
     * Object Name must be unique within a given BACnet network.
     *
     * @return A string containing the Object's Name property.
     */
    virtual std::string getDeviceName();

    /**
     * Set the Device Object's Name property.  This must be a string
     * containing at least one character and no more than 63
     * characters.  Note, according to the spec, the Device Object
     * Name must be unique within a given BACnet network.
     *
     * @param name The name to set.
     * @return true if the operation succeeded, false otherwise
     */
    virtual bool setDeviceName(std::string name);

    /**
     * This is a utility function that will return a string reporting
     * on the various types of errors that can occur in BACnet
     * operation.
     *
     * @return A string containing the last error message.
     */
    virtual std::string getAllErrorString();

    /**
     * Return an enumration of the last error type to occur.  The
     * value returned will be one of the BACNETMSTP::BACERR_TYPE_T
     * values.
     *
     * @return The last error type to occur, one of the
     * BACNETMSTP::BACERR_TYPE_T values.
     */
    virtual BACNETMSTP::BACERR_TYPE_T getErrorType();

    /**
     * In the event of a BACnet Reject error, return the error code.
     *
     * @return The Reject error code.
     */
    virtual uint8_t getRejectReason();

    /**
     * In the event of a BACnet Reject error, return the error string.
     *
     * @return The Reject error string.
     */
    virtual std::string getRejectString();

    /**
     * In the event of a BACnet Abort error, return the Abort reason code.
     *
     * @return The Abort reason code.
     */
    virtual uint8_t getAbortReason();

    /**
     * In the event of a BACnet Abort error, return the Abort string.
     *
     * @return The Abort error string.
     */
    virtual std::string getAbortString();

    /**
     * In the event of a general BACnet error, return the BACnet error class.
     *
     * @return One of the BACNET_ERROR_CLASS error class codes
     */
    virtual BACNET_ERROR_CLASS getErrorClass();

    /**
     * In the event of a general BACnet error, return the BACnet error code.
     *
     * @return One of the BACNET_ERROR_CODE error codes
     */
    virtual BACNET_ERROR_CODE getErrorCode();

    /**
     * In the event of a general BACnet error, return the BACnet error
     * string.
     *
     * @return A string representing the BACnet error class and code.
     */
    virtual std::string getErrorString();

    /**
     * In the event of a non-BACnet UPM error, return a string
     * describing the error.
     *
     * @return A string representing the UPM error.
     */
    virtual std::string getUPMErrorString();

  protected:
    // update our stored info for an MSV
    virtual void updateMultiStateValueInfo(uint32_t objInstance);
    // delete our stored info for an MSV
    virtual void deleteMultiStateValueInfo(uint32_t objInstance);

    // update our stored info for a BV
    virtual void updateBinaryValueInfo(uint32_t objInstance);
    // delete our stored info for a BV
    virtual void deleteBinaryValueInfo(uint32_t objInstance);

    // update our stored info for a BI
    virtual void updateBinaryInputInfo(uint32_t objInstance);
    // delete our stored info for a BI
    virtual void deleteBinaryInputInfo(uint32_t objInstance);

    // also enable mstp debugging in BACNETMSTP
    bool m_debugging;

    // whether or not to verify reliability before reading a value.
    bool m_checkReliability;

    // our target Device Object ID
    uint32_t m_targetDeviceObjectID;

    // a copy of the BACNETMSTP singleton instance pointer
    BACNETMSTP* m_instance;

    // are we initialized?
    bool m_initialized;

    // storage for Binary Input and Binary Value Data.  This will
    // generate SWIG warnings which can be ignored as we do not expose
    // this struct outside the class.
    typedef struct {
      std::string inactiveText;
      std::string activeText;
    } binaryData_t;

    typedef std::map<uint32_t, binaryData_t> binaryInfo_t;

    // storage for binary input/value information
    binaryInfo_t m_bvInfo;
    binaryInfo_t m_biInfo;

    // storage for multi-state data.  This will generate SWIG
    // warnings which can be ignored as we do not expose this struct
    // outside the class.
    typedef struct {
      unsigned int numStates;
      std::vector<std::string>stateList;
    } multiStateData_t;

    // our information storage for MSV's
    typedef std::map<uint32_t, multiStateData_t> multiStateInfo_t;

    multiStateInfo_t m_msvInfo;

    // Unit cache for AV
    typedef std::map<uint32_t, std::string> avCacheMap_t;
    avCacheMap_t m_avUnitCache;

    // Unit cache for AI
    typedef std::map<uint32_t, std::string> aiCacheMap_t;
    aiCacheMap_t m_aiUnitCache;

  private:
  };
}