1 /* 2 LinKNX KNX home automation platform 3 Copyright (C) 2007-2009 Jean-François Meessen <linknx@ouaye.net> 4 5 This program is free software; you can redistribute it and/or modify 6 it under the terms of the GNU General Public License as published by 7 the Free Software Foundation; either version 2 of the License, or 8 (at your option) any later version. 9 10 This program is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 GNU General Public License for more details. 14 15 You should have received a copy of the GNU General Public License 16 along with this program; if not, write to the Free Software 17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 */ 19 20 #ifndef IOPORT_H 21 #define IOPORT_H 22 23 #include "config.h" 24 #include "logger.h" 25 #include "threads.h" 26 #include <string> 27 #include <memory> 28 #include "ticpp.h" 29 #include "ruleserver.h" 30 #include <sys/socket.h> 31 #include <netinet/in.h> 32 #include <arpa/inet.h> 33 #include <termios.h> 34 #include <regex.h> 35 36 37 38 class IOPortListener 39 { 40 public: ~IOPortListener()41 virtual ~IOPortListener() {}; 42 virtual void onDataReceived(const uint8_t* buf, unsigned int len) = 0; 43 }; 44 45 class RxThread; 46 class ConnectCondition; 47 class IOPort; 48 49 class IOPortManager 50 { 51 public: 52 static IOPortManager* instance(); reset()53 static void reset() 54 { 55 if (instance_m) 56 delete instance_m; 57 instance_m = 0; 58 }; 59 void addPort(IOPort* conn); 60 void removePort(IOPort* conn); 61 62 IOPort* getPort(const std::string& id); 63 64 virtual void importXml(ticpp::Element* pConfig); 65 virtual void exportXml(ticpp::Element* pConfig); 66 67 // virtual void exportObjectValues(ticpp::Element* pObjects); 68 69 private: 70 IOPortManager(); 71 virtual ~IOPortManager(); 72 73 typedef std::pair<std::string ,IOPort*> IOPortPair_t; 74 typedef std::map<std::string ,IOPort*> IOPortMap_t; 75 IOPortMap_t portMap_m; 76 static IOPortManager* instance_m; 77 }; 78 79 class IOPort 80 { 81 public: 82 enum Direction 83 { 84 In, 85 Out, 86 InOut 87 }; 88 89 IOPort(); 90 virtual ~IOPort(); 91 92 static IOPort* create(ticpp::Element* pConfig); 93 static IOPort* create(const std::string& type); 94 95 virtual void importXml(ticpp::Element* pConfig); 96 virtual void exportXml(ticpp::Element* pConfig); 97 setID(const char * id)98 void setID(const char* id) { id_m = id; }; getID()99 const char* getID() { return id_m.c_str(); }; 100 101 void addListener(IOPortListener *l); // { if (rxThread_m) rxThread_m->addListener(l); }; 102 bool removeListener(IOPortListener *l); // { if (rxThread_m) return (rxThread_m->removeListener(l)) else return false; }; 103 void addConnectListener(ConnectCondition *c); 104 bool removeConnectListener(ConnectCondition *c); 105 void onConnect(); 106 virtual bool isRxEnabled() = 0; 107 virtual bool mustConnect() = 0; 108 virtual int send(const uint8_t* buf, int len) = 0; 109 virtual int get(uint8_t* buf, int len, pth_event_t stop) = 0; 110 111 private: 112 std::auto_ptr<RxThread> rxThread_m; 113 std::string id_m; 114 115 typedef std::list<ConnectCondition*> ConnectListenerList_t; 116 ConnectListenerList_t connectListenerList_m; 117 118 // Direction dir_m; 119 120 static Logger& logger_m; 121 }; 122 123 class RxThread : public Thread 124 { 125 public: 126 RxThread(IOPort *port); 127 virtual ~RxThread(); 128 startPort()129 void startPort() { isRunning_m = true; Start(); }; stopPort()130 void stopPort() { isRunning_m = false; Stop(); }; 131 132 void addListener(IOPortListener *listener); 133 bool removeListener(IOPortListener *listener); 134 135 private: 136 IOPort *port_m; 137 bool isRunning_m; 138 pth_event_t stop_m; 139 typedef std::list<IOPortListener*> ListenerList_t; 140 ListenerList_t listenerList_m; 141 142 void Run (pth_sem_t * stop); 143 static Logger& logger_m; 144 }; 145 146 class UdpIOPort : public IOPort 147 { 148 public: 149 UdpIOPort(); 150 virtual ~UdpIOPort(); 151 152 virtual void importXml(ticpp::Element* pConfig); 153 virtual void exportXml(ticpp::Element* pConfig); 154 155 int send(const uint8_t* buf, int len); 156 int get(uint8_t* buf, int len, pth_event_t stop); isRxEnabled()157 virtual bool isRxEnabled() { return rxport_m > 0; }; mustConnect()158 virtual bool mustConnect() { return false; }; 159 160 private: 161 std::string host_m; 162 int sockfd_m; 163 int port_m; 164 int rxport_m; 165 struct sockaddr_in addr_m; 166 static Logger& logger_m; 167 }; 168 169 class TcpClientIOPort : public IOPort 170 { 171 public: 172 TcpClientIOPort(); 173 virtual ~TcpClientIOPort(); 174 175 virtual void importXml(ticpp::Element* pConfig); 176 virtual void exportXml(ticpp::Element* pConfig); 177 178 int send(const uint8_t* buf, int len); 179 int get(uint8_t* buf, int len, pth_event_t stop); isRxEnabled()180 virtual bool isRxEnabled() { return permanent_m; }; mustConnect()181 virtual bool mustConnect() { return true; }; 182 183 private: 184 struct Socket 185 { 186 Socket(TcpClientIOPort *ioport); 187 188 ~Socket(); 189 190 TcpClientIOPort *ioport_m; 191 int sockfd_m; 192 }; 193 194 std::string host_m; 195 // Permanent socket or -1 if connection is not permanent. 196 int permanentSockfd_m; 197 int port_m; 198 bool permanent_m; 199 struct sockaddr_in addr_m; 200 static Logger& logger_m; 201 202 // void connectToServer(); 203 // void disconnectFromServer(); 204 }; 205 206 class SerialIOPort : public IOPort 207 { 208 public: 209 SerialIOPort(); 210 virtual ~SerialIOPort(); 211 212 virtual void importXml(ticpp::Element* pConfig); 213 virtual void exportXml(ticpp::Element* pConfig); 214 215 int send(const uint8_t* buf, int len); 216 int get(uint8_t* buf, int len, pth_event_t stop); isRxEnabled()217 virtual bool isRxEnabled() { return true; }; mustConnect()218 virtual bool mustConnect() { return true; }; 219 220 private: 221 std::string dev_m; 222 speed_t speed_m; 223 int fd_m; 224 bool modeRaw_m; 225 int timeout_m; 226 int msglength_m; 227 struct termios oldtio_m, newtio_m; 228 static Logger& logger_m; 229 }; 230 231 class TxAction : public Action 232 { 233 public: 234 TxAction(); 235 virtual ~TxAction(); 236 237 virtual void importXml(ticpp::Element* pConfig); 238 virtual void exportXml(ticpp::Element* pConfig); 239 240 void sendData(IOPort* port); 241 private: 242 virtual void Run (pth_sem_t * stop); 243 244 int varFlags_m; 245 enum replaceVarFlags 246 { 247 VarEnabled = 1, 248 VarData = 2, 249 }; 250 std::string data_m; 251 std::string port_m; 252 bool hex_m; 253 }; 254 255 class RxCondition : public Condition, public IOPortListener 256 { 257 public: 258 RxCondition(ChangeListener* cl); 259 virtual ~RxCondition(); 260 261 virtual bool evaluate(); 262 virtual void importXml(ticpp::Element* pConfig); 263 virtual void exportXml(ticpp::Element* pConfig); 264 virtual void statusXml(ticpp::Element* pStatus); 265 266 virtual void onDataReceived(const uint8_t* buf, unsigned int len); 267 268 private: 269 std::string port_m; 270 std::string exp_m; 271 regex_t regex_m; 272 bool regexFlag_m; 273 bool value_m; 274 bool hex_m; 275 regmatch_t* pmatch_m; 276 std::vector<Object*> objects_m; 277 ChangeListener* cl_m; 278 }; 279 280 class ConnectCondition : public Condition 281 { 282 public: 283 ConnectCondition(ChangeListener* cl); 284 virtual ~ConnectCondition(); 285 286 virtual bool evaluate(); 287 virtual void importXml(ticpp::Element* pConfig); 288 virtual void exportXml(ticpp::Element* pConfig); 289 virtual void statusXml(ticpp::Element* pStatus); 290 291 virtual void onConnect(); 292 293 private: 294 std::string port_m; 295 bool value_m; 296 ChangeListener* cl_m; 297 }; 298 299 300 #endif 301