UniSet  2.6.0
MessageType.h
00001 /*
00002  * Copyright (c) 2015 Pavel Vainerman.
00003  *
00004  * This program is free software: you can redistribute it and/or modify
00005  * it under the terms of the GNU Lesser General Public License as
00006  * published by the Free Software Foundation, version 2.1.
00007  *
00008  * This program is distributed in the hope that it will be useful, but
00009  * WITHOUT ANY WARRANTY; without even the implied warranty of
00010  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
00011  * Lesser General Lesser Public License for more details.
00012  *
00013  * You should have received a copy of the GNU Lesser General Public License
00014  * along with this program. If not, see <http://www.gnu.org/licenses/>.
00015  */
00016 // --------------------------------------------------------------------------
00021 // --------------------------------------------------------------------------
00022 #ifndef MessageType_H_
00023 #define MessageType_H_
00024 // --------------------------------------------------------------------------
00025 #include <time.h> // for timespec
00026 #include <cstring>
00027 #include <ostream>
00028 #include "UniSetTypes.h"
00029 #include "IOController_i.hh"
00030 // --------------------------------------------------------------------------
00031 namespace uniset
00032 {
00033 class Message
00034 {
00035     public:
00036         enum TypeOfMessage
00037         {
00038             Unused,        // Сообщение не содержит информации
00039             SensorInfo,
00040             SysCommand, // Сообщение содержит системную команду
00041             Confirm,    // Сообщение содержит подтверждение
00042             Timer,        // Сообщения о срабатывании таймера
00043             TheLastFieldOfTypeOfMessage // Обязательно оставьте последним
00044         };
00045 
00046         int type = { Unused };    // Содержание сообщения (тип)
00047 
00048         enum Priority
00049         {
00050             Low,
00051             Medium,
00052             High
00053         };
00054 
00055         Priority priority = { Medium };
00056         ObjectId node = { uniset::DefaultObjectId };      // откуда
00057         ObjectId supplier = { uniset::DefaultObjectId };  // от кого
00058         ObjectId consumer = { uniset::DefaultObjectId };  // кому
00059         struct timespec tm = { 0, 0 };
00060 
00061         Message( Message&& ) noexcept = default;
00062         Message& operator=(Message&& ) noexcept = default;
00063         Message( const Message& ) noexcept = default;
00064         Message& operator=(const Message& ) noexcept = default;
00065 
00066         Message() noexcept;
00067 
00068         // для оптимизации, делаем конструктор который не будет инициализировать свойства класса
00069         // это необходимо для VoidMessage, который конструируется при помощи memcpy
00070         explicit Message( int dummy_init ) noexcept {}
00071 
00072         template<class In>
00073         static const TransportMessage transport(const In& msg) noexcept
00074         {
00075             TransportMessage tmsg;
00076             assert(sizeof(uniset::RawDataOfTransportMessage) >= sizeof(msg));
00077             std::memcpy(&tmsg.data, &msg, sizeof(msg));
00078             tmsg.consumer = msg.consumer;
00079             return std::move(tmsg);
00080         }
00081 };
00082 
00083 std::ostream& operator<<( std::ostream& os, const Message::TypeOfMessage& t );
00084 
00085 // ------------------------------------------------------------------------
00086 class VoidMessage : public Message
00087 {
00088     public:
00089 
00090         VoidMessage( VoidMessage&& ) noexcept = default;
00091         VoidMessage& operator=(VoidMessage&& ) noexcept = default;
00092         VoidMessage( const VoidMessage& ) noexcept = default;
00093         VoidMessage& operator=( const VoidMessage& ) noexcept = default;
00094 
00095         // для оптимизации, делаем конструктор который не будет инициализировать свойства класса
00096         // это необходимо для VoidMessage, который конструируется при помощи memcpy
00097         VoidMessage( int dummy ) noexcept : Message(dummy) {}
00098 
00099         VoidMessage( const TransportMessage& tm ) noexcept;
00100         VoidMessage() noexcept;
00101         inline bool operator < ( const VoidMessage& msg ) const
00102         {
00103             if( priority != msg.priority )
00104                 return priority < msg.priority;
00105 
00106             if( tm.tv_sec != msg.tm.tv_sec )
00107                 return tm.tv_sec >= msg.tm.tv_sec;
00108 
00109             return tm.tv_nsec >= msg.tm.tv_nsec;
00110         }
00111 
00112         inline TransportMessage transport_msg() const noexcept
00113         {
00114             return transport(*this);
00115         }
00116 
00117         uniset::ByteOfMessage data[sizeof(uniset::RawDataOfTransportMessage) - sizeof(Message)];
00118 };
00119 
00120 // ------------------------------------------------------------------------
00122 class SensorMessage : public Message
00123 {
00124     public:
00125 
00126         ObjectId id = { uniset::DefaultObjectId };
00127         long value = { 0 };
00128         bool undefined = { false };
00129 
00130         // время изменения состояния датчика
00131         struct timespec sm_tv = { 0, 0 };
00132 
00133         UniversalIO::IOType sensor_type = { UniversalIO::DI };
00134         IOController_i::CalibrateInfo ci;
00135 
00136         // для пороговых датчиков
00137         bool threshold = { false };  
00138         uniset::ThresholdId tid = { uniset::DefaultThresholdId };
00139 
00140         SensorMessage( SensorMessage&& m) noexcept = default;
00141         SensorMessage& operator=(SensorMessage&& m) noexcept = default;
00142         SensorMessage( const SensorMessage& ) noexcept = default;
00143         SensorMessage& operator=( const SensorMessage& ) noexcept = default;
00144 
00145         SensorMessage() noexcept;
00146         SensorMessage(ObjectId id, long value, const IOController_i::CalibrateInfo& ci = IOController_i::CalibrateInfo(),
00147                       Priority priority = Message::Medium,
00148                       UniversalIO::IOType st = UniversalIO::AI,
00149                       ObjectId consumer = uniset::DefaultObjectId) noexcept;
00150 
00151         // специальный конструктор, для оптимизации
00152         // он не инициализирует поля по умолчанию
00153         // и за инициализацию значений отвечает "пользователь"
00154         // например см. IONotifyController::localSetValue()
00155         explicit SensorMessage( int dummy ) noexcept;
00156 
00157         SensorMessage(const VoidMessage* msg) noexcept;
00158         inline TransportMessage transport_msg() const noexcept
00159         {
00160             return transport(*this);
00161         }
00162 };
00163 
00164 // ------------------------------------------------------------------------
00166 class SystemMessage : public Message
00167 {
00168     public:
00169         enum Command
00170         {
00171             Unknown,
00172             StartUp,    
00173             FoldUp,     
00174             Finish,     
00175             WatchDog,   
00176             ReConfiguration,        
00177             NetworkInfo,            
00182             LogRotate,    
00183             TheLastFieldOfCommand
00184         };
00185 
00186         SystemMessage( SystemMessage&& ) noexcept = default;
00187         SystemMessage& operator=(SystemMessage&& ) noexcept = default;
00188         SystemMessage( const SystemMessage& ) noexcept = default;
00189         SystemMessage& operator=( const SystemMessage& ) noexcept = default;
00190 
00191         SystemMessage() noexcept;
00192         SystemMessage(Command command, Priority priority = Message::High,
00193                       ObjectId consumer = uniset::DefaultObjectId) noexcept;
00194         SystemMessage(const VoidMessage* msg) noexcept;
00195 
00196         inline TransportMessage transport_msg() const noexcept
00197         {
00198             return transport(*this);
00199         }
00200 
00201         int command;
00202         long data[2];
00203 };
00204 std::ostream& operator<<( std::ostream& os, const SystemMessage::Command& c );
00205 
00206 // ------------------------------------------------------------------------
00207 
00209 class TimerMessage : public Message
00210 {
00211     public:
00212         TimerMessage( TimerMessage&& ) noexcept = default;
00213         TimerMessage& operator=(TimerMessage&& ) noexcept = default;
00214         TimerMessage( const TimerMessage& ) noexcept = default;
00215         TimerMessage& operator=( const TimerMessage& ) noexcept = default;
00216 
00217         TimerMessage();
00218         TimerMessage(uniset::TimerId id, Priority prior = Message::High,
00219                      ObjectId cons = uniset::DefaultObjectId);
00220         TimerMessage(const VoidMessage* msg) noexcept ;
00221         inline TransportMessage transport_msg() const noexcept
00222         {
00223             return transport(*this);
00224         }
00225 
00226         uniset::TimerId id; 
00227 };
00228 
00229 // ------------------------------------------------------------------------
00230 
00232 class ConfirmMessage: public Message
00233 {
00234     public:
00235 
00236         inline TransportMessage transport_msg() const noexcept
00237         {
00238             return transport(*this);
00239         }
00240 
00241         ConfirmMessage( const VoidMessage* msg ) noexcept;
00242 
00243         ConfirmMessage(ObjectId in_sensor_id,
00244                        const double& in_sensor_value,
00245                        const timespec& in_sensor_time,
00246                        const timespec& in_confirm_time,
00247                        Priority in_priority = Message::Medium) noexcept;
00248 
00249         ConfirmMessage( ConfirmMessage&& ) noexcept = default;
00250         ConfirmMessage& operator=(ConfirmMessage&& ) noexcept = default;
00251         ConfirmMessage( const ConfirmMessage& ) noexcept = default;
00252         ConfirmMessage& operator=( const ConfirmMessage& ) noexcept = default;
00253 
00254         ObjectId sensor_id;   /* ID датчика (события) */
00255         double sensor_value;  /* значение датчика (события) */
00256         struct timespec sensor_time;    /* время срабатывания датчика(события), который квитируем */
00257         struct timespec confirm_time;   /* * время прошедшее до момента квитирования */
00258 
00259         bool broadcast;
00260 
00266         bool forward;
00267 
00268     protected:
00269         ConfirmMessage() noexcept;
00270 };
00271 
00272 }
00273 // --------------------------------------------------------------------------
00274 #endif // MessageType_H_