upm  1.6.0
Sensor/Actuator repository for libmraa (v1.9.0)
bacnetmstp.hpp
1 /*
2  * Author: Jon Trulson <jtrulson@ics.com>
3  * Copyright (c) 2016 Intel Corporation.
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining
6  * a copy of this software and associated documentation files (the
7  * "Software"), to deal in the Software without restriction, including
8  * without limitation the rights to use, copy, modify, merge, publish,
9  * distribute, sublicense, and/or sell copies of the Software, and to
10  * permit persons to whom the Software is furnished to do so, subject to
11  * the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be
14  * included in all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20  * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21  * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23  */
24 #pragma once
25 
26 #include <string>
27 #include <vector>
28 
29 // we only support a BACnet RS-485 MS/TP datalink
30 #define BACDL_MSTP 1
31 #undef BACDL_ALL
32 
33 // get a variety of bacnet-stack includes...
34 #include "bacdef.h"
35 #include "config.h"
36 #include "bactext.h"
37 #include "bacerror.h"
38 #include "iam.h"
39 #include "arf.h"
40 #include "tsm.h"
41 #include "address.h"
42 #include "npdu.h"
43 #include "apdu.h"
44 #include "device.h"
45 #include "datalink.h"
46 #include "whois.h"
47 #include "mstpdef.h"
48 #include "dlmstp.h"
49 
50 
51 namespace upm {
52 
104  class BACNETMSTP {
105  // Constructor and destructor are protected
106 
107  public:
108 
109  // error types
110  typedef enum {
111  BACERR_TYPE_NONE = 0,
112  BACERR_TYPE_REJECT,
113  BACERR_TYPE_ABORT,
114  BACERR_TYPE_ERROR,
115  BACERR_TYPE_UPM
116  } BACERR_TYPE_T;
117 
118  // command types we currently support
119  typedef enum {
120  BACCMD_NONE = 0,
121  BACCMD_READ_PROPERTY,
122  BACCMD_WRITE_PROPERTY
123  } BACCMD_TYPE_T;
124 
132  static BACNETMSTP* instance();
133 
163  void initMaster(std::string port, int baudRate, int deviceInstanceNumber,
164  int macAddr, int maxMaster=DEFAULT_MAX_MASTER,
165  int maxInfoFrames=1);
166 
167 
192  bool readProperty(uint32_t targetDeviceInstanceID,
193  BACNET_OBJECT_TYPE objType,
194  uint32_t objInstance,
195  BACNET_PROPERTY_ID objProperty,
196  uint32_t arrayIndex=BACNET_ARRAY_ALL);
197 
231  bool writeProperty(uint32_t targetDeviceInstanceID,
232  BACNET_OBJECT_TYPE objType,
233  uint32_t objInstance,
234  BACNET_PROPERTY_ID objProperty,
235  BACNET_APPLICATION_DATA_VALUE* propValue,
236  uint8_t propPriority=BACNET_NO_PRIORITY,
237  int32_t arrayIndex=BACNET_ARRAY_ALL);
238 
249  BACNET_APPLICATION_DATA_VALUE getData(int index=0);
250 
258  int getDataNumElements();
259 
269  uint8_t getDataType(int index=0);
270 
282  float getDataTypeReal(int index=0);
283 
295  bool getDataTypeBoolean(int index=0);
296 
308  unsigned int getDataTypeUnsignedInt(int index=0);
309 
321  int getDataTypeSignedInt(int index=0);
322 
335  std::string getDataTypeString(int index=0);
336 
347  unsigned int getDataTypeEnum(int index=0);
348 
349 #if defined(BACAPP_DOUBLE)
350 
361  double getDataTypeDouble(int index=0);
362 #endif // BACAPP_DOUBLE
363 
373  BACNET_APPLICATION_DATA_VALUE createDataReal(float Real);
374 
384  BACNET_APPLICATION_DATA_VALUE createDataBool(bool value);
385 
395  BACNET_APPLICATION_DATA_VALUE createDataSignedInt(int value);
396 
407  BACNET_APPLICATION_DATA_VALUE createDataUnsignedInt(unsigned int value);
408 
419  BACNET_APPLICATION_DATA_VALUE createDataString(std::string value);
420 
431  BACNET_APPLICATION_DATA_VALUE createDataEnum(uint32_t value);
432 
440  BACERR_TYPE_T getErrorType()
441  {
442  return m_errorType;
443  };
444 
450  uint8_t getRejectReason()
451  {
452  return m_rejectReason;
453  };
454 
460  std::string getRejectString()
461  {
462  return m_rejectString;
463  };
464 
470  uint8_t getAbortReason()
471  {
472  return m_abortReason;
473  };
474 
480  std::string getAbortString()
481  {
482  return m_abortString;
483  };
484 
490  BACNET_ERROR_CLASS getErrorClass()
491  {
492  return m_errorClass;
493  };
494 
500  BACNET_ERROR_CODE getErrorCode()
501  {
502  return m_errorCode;
503  };
504 
511  std::string getErrorString()
512  {
513  return m_errorString;
514  };
515 
522  std::string getUPMErrorString()
523  {
524  return m_upmErrorString;
525  };
526 
534  {
535  return m_initialized;
536  };
537 
543  std::string getPort()
544  {
545  return m_port;
546  };
547 
555  {
556  return m_deviceInstanceID;
557  };
558 
565  {
566  return m_maxInfoFrames;
567  };
568 
575  {
576  return m_maxMaster;
577  };
578 
585  {
586  return m_baudRate;
587  };
588 
595  {
596  return m_macAddr;
597  };
598 
604  void setDebug(bool enable);
605 
606  protected:
610  BACNETMSTP();
611 
615  ~BACNETMSTP();
616 
617  // clear/reset error states
618  void clearErrors();
619 
620  // error handler
621  static void handlerError(BACNET_ADDRESS * src,
622  uint8_t invoke_id,
623  BACNET_ERROR_CLASS error_class,
624  BACNET_ERROR_CODE error_code);
625 
626  // abort handler
627  static void handlerAbort(BACNET_ADDRESS * src,
628  uint8_t invoke_id,
629  uint8_t abort_reason,
630  bool server);
631 
632  // reject handler
633  static void handlerReject(BACNET_ADDRESS * src,
634  uint8_t invoke_id,
635  uint8_t reject_reason);
636 
637 
638  // our handler for dealing with return data from a ReadProperty call
639  static void handlerReadPropertyAck(uint8_t* service_request,
640  uint16_t service_len,
641  BACNET_ADDRESS* src,
642  BACNET_CONFIRMED_SERVICE_ACK_DATA* service_data);
643 
644  // our handler for writeProp acks
645  static void handlerWritePropertyAck(BACNET_ADDRESS* src,
646  uint8_t invoke_id);
647 
648  // initialize our service handlers
649  void initServiceHandlers();
650 
651  // utility function
652  std::string string2HexString(std::string input);
653 
654  // responsible for dispatching a request to the BACnet network
655  bool dispatchRequest();
656 
657  private:
658  // prevent copying and assignment
659  BACNETMSTP(BACNETMSTP const &) = delete;
660  BACNETMSTP& operator=(BACNETMSTP const&) = delete;
661 
662  // our class instance
663  static BACNETMSTP* m_instance;
664 
665  // has the class been created yet?
666  bool m_initialized;
667 
668  // Some items we can set for our master
669  std::string m_port;
670  int m_maxInfoFrames;
671  int m_maxMaster;
672  int m_baudRate;
673  int m_macAddr;
674 
675  // the unique Instance Number of our Master Device Object
676  uint32_t m_deviceInstanceID;
677 
678  // adpu timeout in milliseconds
679  uint16_t m_adpuTimeoutMS;
680 
681  // buffer used for receiving data
682  uint8_t m_rxBuffer[MAX_MPDU];
683 
684  // our error classfication
685  BACERR_TYPE_T m_errorType;
686 
687  // BACnet reject info
688  uint8_t m_rejectReason;
689  std::string m_rejectString;
690 
691  // BACnet abort info
692  uint8_t m_abortReason;
693  std::string m_abortString;
694 
695  // BACnet error info
696  BACNET_ERROR_CLASS m_errorClass;
697  BACNET_ERROR_CODE m_errorCode;
698  std::string m_errorString;
699 
700  // generic UPM related errors - we just set the error text to
701  // something informative.
702  std::string m_upmErrorString;
703 
704  // our returned data from readProperty()
705  std::vector<BACNET_APPLICATION_DATA_VALUE> m_returnedValue;
706 
707  // current bound target address of dispatched service request
708  // (read/write prop, etc)
709  BACNET_ADDRESS m_targetAddress;
710 
711  // current invokeID (for transaction handling)
712  uint8_t m_invokeID;
713 
714  // error detected flag
715  bool m_errorDetected;
716 
717  // Commands - we create a struct to hold the arguments for each
718  // command type we support. Then, we create a command struct
719  // which contains the command type and a union containing the
720  // relevant arguments. This is used by dispatchRequest() to issue
721  // the correct request.
722 
723  // these may generate SWIG warnings, but they can be ignored as we
724  // do not expose these outside the class
725  typedef struct {
726  uint32_t targetDeviceInstanceID;
727  BACNET_OBJECT_TYPE objType;
728  uint32_t objInstance;
729  BACNET_PROPERTY_ID objProperty;
730  uint32_t arrayIndex;
731  } READ_PROPERTY_ARGS_T;
732 
733  typedef struct {
734  uint32_t targetDeviceInstanceID;
735  BACNET_OBJECT_TYPE objType;
736  uint32_t objInstance;
737  BACNET_PROPERTY_ID objProperty;
738  BACNET_APPLICATION_DATA_VALUE* propValue;
739  uint8_t propPriority;
740  int32_t arrayIndex;
741  } WRITE_PROPERTY_ARGS_T;
742 
743  struct {
744  BACCMD_TYPE_T cmd;
745 
746  union {
747  READ_PROPERTY_ARGS_T readPropArgs;
748  WRITE_PROPERTY_ARGS_T writePropArgs;
749  };
750  } m_command;
751 
752  bool m_debugging;
753  };
754 }
UPM API for BACNETMSTP.
Definition: bacnetmstp.hpp:104
int getMaxInfoFrames()
Definition: bacnetmstp.hpp:564
std::string getErrorString()
Definition: bacnetmstp.hpp:511
std::string getUPMErrorString()
Definition: bacnetmstp.hpp:522
std::string getDataTypeString(int index=0)
Definition: bacnetmstp.cxx:767
std::string getRejectString()
Definition: bacnetmstp.hpp:460
int getDataTypeSignedInt(int index=0)
Definition: bacnetmstp.cxx:714
uint32_t getDeviceInstanceID()
Definition: bacnetmstp.hpp:554
void setDebug(bool enable)
Definition: bacnetmstp.cxx:75
bool getDataTypeBoolean(int index=0)
Definition: bacnetmstp.cxx:692
static BACNETMSTP * instance()
Definition: bacnetmstp.cxx:280
bool isInitialized()
Definition: bacnetmstp.hpp:533
uint8_t getDataType(int index=0)
Definition: bacnetmstp.cxx:660
BACERR_TYPE_T getErrorType()
Definition: bacnetmstp.hpp:440
uint8_t getAbortReason()
Definition: bacnetmstp.hpp:470
float getDataTypeReal(int index=0)
Definition: bacnetmstp.cxx:665
BACNET_APPLICATION_DATA_VALUE createDataEnum(uint32_t value)
Definition: bacnetmstp.cxx:911
C++ API for the kxtj3 driver.
Definition: a110x.hpp:29
unsigned int getDataTypeUnsignedInt(int index=0)
Definition: bacnetmstp.cxx:703
BACNET_APPLICATION_DATA_VALUE createDataUnsignedInt(unsigned int value)
Definition: bacnetmstp.cxx:878
BACNET_APPLICATION_DATA_VALUE getData(int index=0)
Definition: bacnetmstp.cxx:650
int getDataNumElements()
Definition: bacnetmstp.cxx:655
BACNET_APPLICATION_DATA_VALUE createDataSignedInt(int value)
Definition: bacnetmstp.cxx:866
int getMaxMaster()
Definition: bacnetmstp.hpp:574
BACNET_APPLICATION_DATA_VALUE createDataString(std::string value)
Definition: bacnetmstp.cxx:890
std::string getPort()
Definition: bacnetmstp.hpp:543
bool readProperty(uint32_t targetDeviceInstanceID, BACNET_OBJECT_TYPE objType, uint32_t objInstance, BACNET_PROPERTY_ID objProperty, uint32_t arrayIndex=BACNET_ARRAY_ALL)
Definition: bacnetmstp.cxx:578
unsigned int getDataTypeEnum(int index=0)
Definition: bacnetmstp.cxx:756
std::string getAbortString()
Definition: bacnetmstp.hpp:480
BACNET_ERROR_CODE getErrorCode()
Definition: bacnetmstp.hpp:500
BACNET_APPLICATION_DATA_VALUE createDataReal(float Real)
Definition: bacnetmstp.cxx:842
~BACNETMSTP()
Definition: bacnetmstp.cxx:69
uint8_t getRejectReason()
Definition: bacnetmstp.hpp:450
BACNET_ERROR_CLASS getErrorClass()
Definition: bacnetmstp.hpp:490
void initMaster(std::string port, int baudRate, int deviceInstanceNumber, int macAddr, int maxMaster=DEFAULT_MAX_MASTER, int maxInfoFrames=1)
Definition: bacnetmstp.cxx:288
int getBaudRate()
Definition: bacnetmstp.hpp:584
BACNET_APPLICATION_DATA_VALUE createDataBool(bool value)
Definition: bacnetmstp.cxx:854
bool writeProperty(uint32_t targetDeviceInstanceID, BACNET_OBJECT_TYPE objType, uint32_t objInstance, BACNET_PROPERTY_ID objProperty, BACNET_APPLICATION_DATA_VALUE *propValue, uint8_t propPriority=BACNET_NO_PRIORITY, int32_t arrayIndex=BACNET_ARRAY_ALL)
Definition: bacnetmstp.cxx:612
int getMACAddress()
Definition: bacnetmstp.hpp:594
BACNETMSTP()
Definition: bacnetmstp.cxx:44