Merge branch 'master' of git://github.com/yuhu-/ebusd
Conflicts: src/lib/ebus/data.cpp src/lib/ebus/data.h src/lib/ebus/test/test_data.cpp
This commit is contained in:
@@ -12,16 +12,12 @@ libebus_a_SOURCES = result.cpp \
|
||||
data.h \
|
||||
port.cpp \
|
||||
port.h \
|
||||
buscommand.cpp \
|
||||
buscommand.h \
|
||||
command.cpp \
|
||||
command.h \
|
||||
commands.cpp \
|
||||
commands.h \
|
||||
configfile.cpp \
|
||||
configfile.h \
|
||||
dump.cpp \
|
||||
dump.h \
|
||||
decode.cpp \
|
||||
decode.h \
|
||||
encode.cpp \
|
||||
|
||||
@@ -1,69 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) Roland Jax 2012-2014 <ebusd@liwest.at>
|
||||
*
|
||||
* This file is part of ebusd.
|
||||
*
|
||||
* ebusd is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* ebusd is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with ebusd. If not, see http://www.gnu.org/licenses/.
|
||||
*/
|
||||
|
||||
#include "buscommand.h"
|
||||
|
||||
namespace libebus
|
||||
{
|
||||
|
||||
BusCommand::BusCommand(const std::string commandStr, const bool isPoll)
|
||||
: m_isPoll(isPoll), m_command(commandStr), m_result(), m_resultCode(RESULT_OK)
|
||||
{
|
||||
unsigned char dstAddress = m_command[1];
|
||||
|
||||
if (dstAddress == BROADCAST)
|
||||
m_type = broadcast;
|
||||
else if (isMaster(dstAddress) == true)
|
||||
m_type = masterMaster;
|
||||
else
|
||||
m_type = masterSlave;
|
||||
|
||||
pthread_mutex_init(&m_mutex, NULL);
|
||||
pthread_cond_init(&m_cond, NULL);
|
||||
}
|
||||
|
||||
BusCommand::~BusCommand()
|
||||
{
|
||||
pthread_mutex_destroy(&m_mutex);
|
||||
pthread_cond_destroy(&m_cond);
|
||||
}
|
||||
|
||||
const std::string BusCommand::getMessageStr()
|
||||
{
|
||||
std::string result;
|
||||
|
||||
if (m_resultCode >= 0) {
|
||||
if (m_type == masterSlave) {
|
||||
result = m_command.getDataStr();
|
||||
result += "00";
|
||||
result += m_result.getDataStr();
|
||||
result += "00";
|
||||
}
|
||||
else
|
||||
result = "success";
|
||||
}
|
||||
else
|
||||
result = "error: "+std::string(getResultCodeCStr());
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
} //namespace
|
||||
|
||||
@@ -1,70 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) Roland Jax 2012-2014 <ebusd@liwest.at>
|
||||
*
|
||||
* This file is part of ebusd.
|
||||
*
|
||||
* ebusd is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* ebusd is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with ebusd. If not, see http://www.gnu.org/licenses/.
|
||||
*/
|
||||
|
||||
#ifndef LIBEBUS_BUSCOMMAND_H_
|
||||
#define LIBEBUS_BUSCOMMAND_H_
|
||||
|
||||
#include "symbol.h"
|
||||
#include "result.h"
|
||||
|
||||
|
||||
namespace libebus
|
||||
{
|
||||
|
||||
|
||||
enum CommandType { invalid, broadcast, masterMaster, masterSlave };
|
||||
|
||||
class BusCommand
|
||||
{
|
||||
|
||||
public:
|
||||
BusCommand(const std::string command, const bool isPoll);
|
||||
~BusCommand();
|
||||
|
||||
CommandType getType() const { return m_type; }
|
||||
bool isPoll() const { return m_isPoll; }
|
||||
|
||||
SymbolString getCommand() const { return m_command; }
|
||||
SymbolString getResult() const { return m_result; }
|
||||
|
||||
bool isErrorResult() const { return m_resultCode < 0; }
|
||||
const char* getResultCodeCStr() const { return libebus::getResultCodeCStr(m_resultCode); }
|
||||
void setResult(const SymbolString result, const int resultCode)
|
||||
{ m_result = result; m_resultCode = resultCode; }
|
||||
|
||||
const std::string getMessageStr();
|
||||
|
||||
void waitSignal() { pthread_cond_wait(&m_cond, &m_mutex); } // TODO timeout
|
||||
void sendSignal() { pthread_cond_signal(&m_cond); }
|
||||
|
||||
private:
|
||||
CommandType m_type;
|
||||
bool m_isPoll;
|
||||
SymbolString m_command;
|
||||
SymbolString m_result;
|
||||
int m_resultCode;
|
||||
|
||||
pthread_mutex_t m_mutex;
|
||||
pthread_cond_t m_cond;
|
||||
};
|
||||
|
||||
|
||||
} //namespace
|
||||
|
||||
#endif // LIBEBUS_BUSCOMMAND_H_
|
||||
@@ -27,10 +27,6 @@
|
||||
#include <vector>
|
||||
#include <cstring>
|
||||
|
||||
namespace libebus
|
||||
{
|
||||
|
||||
|
||||
std::string Command::calcData()
|
||||
{
|
||||
// encode - only first entry will be encoded
|
||||
@@ -340,6 +336,3 @@ void Command::encode(const std::string& data, const std::string& type,
|
||||
delete help;
|
||||
}
|
||||
|
||||
|
||||
} //namespace
|
||||
|
||||
|
||||
@@ -23,10 +23,6 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace libebus
|
||||
{
|
||||
|
||||
|
||||
typedef std::vector<std::string> cmd_t;
|
||||
typedef cmd_t::const_iterator cmdCI_t;
|
||||
|
||||
@@ -63,7 +59,4 @@ private:
|
||||
|
||||
};
|
||||
|
||||
|
||||
} //namespace
|
||||
|
||||
#endif // LIBEBUS_COMMAND_H_
|
||||
|
||||
+33
-26
@@ -25,16 +25,12 @@
|
||||
#include <vector>
|
||||
#include <cstring>
|
||||
|
||||
namespace libebus
|
||||
{
|
||||
|
||||
|
||||
Commands::~Commands()
|
||||
{
|
||||
for (mapCI_t iter = m_polDB.begin(); iter != m_polDB.end(); ++iter)
|
||||
for (mapCI_t iter = m_pollDB.begin(); iter != m_pollDB.end(); ++iter)
|
||||
delete iter->second;
|
||||
|
||||
m_polDB.clear();
|
||||
m_pollDB.clear();
|
||||
|
||||
for (mapCI_t iter = m_cycDB.begin(); iter != m_cycDB.end(); ++iter)
|
||||
delete iter->second;
|
||||
@@ -55,7 +51,7 @@ void Commands::addCommand(const cmd_t& command)
|
||||
|
||||
if (strcasecmp(command[0].c_str(),"P") == 0) {
|
||||
Command* cmd = new Command(m_cmdDB.size()-1, command);
|
||||
m_polDB.insert(pair_t(m_cmdDB.size()-1, cmd));
|
||||
m_pollDB.insert(pair_t(m_cmdDB.size()-1, cmd));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -127,7 +123,7 @@ int Commands::findCommand(const std::string& data) const
|
||||
return -1;
|
||||
}
|
||||
|
||||
std::string Commands::getEbusCommand(const int index) const
|
||||
std::string Commands::getBusCommand(const int index) const
|
||||
{
|
||||
cmd_t command = m_cmdDB.at(index);
|
||||
std::string cmd;
|
||||
@@ -163,7 +159,7 @@ int Commands::storeCycData(const std::string& data) const
|
||||
// walk through commands
|
||||
for (; iter != m_cycDB.end(); iter++) {
|
||||
|
||||
std::string command = getEbusCommand(iter->first);
|
||||
std::string command = getBusCommand(iter->first);
|
||||
|
||||
// skip wrong search string length
|
||||
if (command.length() > search.length())
|
||||
@@ -188,35 +184,35 @@ std::string Commands::getCycData(int index) const
|
||||
return "";
|
||||
}
|
||||
|
||||
int Commands::nextPolCommand()
|
||||
int Commands::nextPollCommand()
|
||||
{
|
||||
size_t index = 0;
|
||||
|
||||
m_polIndex++;
|
||||
m_pollIndex++;
|
||||
|
||||
if (m_polIndex == m_polDB.size())
|
||||
m_polIndex = 0;
|
||||
if (m_pollIndex == m_pollDB.size())
|
||||
m_pollIndex = 0;
|
||||
|
||||
mapCI_t iter = m_polDB.begin();
|
||||
mapCI_t iter = m_pollDB.begin();
|
||||
|
||||
for (; iter != m_polDB.end(); iter++, index++)
|
||||
if (index == m_polIndex)
|
||||
for (; iter != m_pollDB.end(); iter++, index++)
|
||||
if (index == m_pollIndex)
|
||||
return iter->first;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
void Commands::storePolData(const std::string& data) const
|
||||
void Commands::storePollData(const std::string& data) const
|
||||
{
|
||||
// prepare string for searching command
|
||||
std::string search(data.substr(2, 8 + strtol(data.substr(8,2).c_str(), NULL, 16) * 2));
|
||||
|
||||
mapCI_t iter = m_polDB.begin();
|
||||
mapCI_t iter = m_pollDB.begin();
|
||||
|
||||
// walk through commands
|
||||
for (; iter != m_polDB.end(); iter++) {
|
||||
for (; iter != m_pollDB.end(); iter++) {
|
||||
|
||||
std::string command = getEbusCommand(iter->first);
|
||||
std::string command = getBusCommand(iter->first);
|
||||
|
||||
// skip wrong search string length
|
||||
if (command.length() > search.length())
|
||||
@@ -228,15 +224,29 @@ void Commands::storePolData(const std::string& data) const
|
||||
}
|
||||
}
|
||||
|
||||
std::string Commands::getPolData(int index) const
|
||||
std::string Commands::getPollData(const int index) const
|
||||
{
|
||||
mapCI_t iter = m_polDB.find(index);
|
||||
if (iter != m_polDB.end())
|
||||
mapCI_t iter = m_pollDB.find(index);
|
||||
if (iter != m_pollDB.end())
|
||||
return iter->second->getData();
|
||||
else
|
||||
return "";
|
||||
}
|
||||
|
||||
void Commands::storeScanData(const std::string& data)
|
||||
{
|
||||
std::vector<std::string>::const_iterator iter = m_scanDB.begin();
|
||||
bool found = false;
|
||||
|
||||
// walk through scan data
|
||||
for (; iter != m_scanDB.end(); iter++)
|
||||
if (data == (*iter))
|
||||
found = true;
|
||||
|
||||
if (found == false)
|
||||
m_scanDB.push_back(data);
|
||||
}
|
||||
|
||||
void Commands::printCommand(const cmd_t& command) const
|
||||
{
|
||||
if (command.size() == 0)
|
||||
@@ -246,6 +256,3 @@ void Commands::printCommand(const cmd_t& command) const
|
||||
std::cout << *i << ';';
|
||||
}
|
||||
|
||||
|
||||
} //namespace
|
||||
|
||||
|
||||
+14
-15
@@ -25,10 +25,6 @@
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
namespace libebus
|
||||
{
|
||||
|
||||
|
||||
typedef std::vector<cmd_t> cmdDB_t;
|
||||
typedef cmdDB_t::const_iterator cmdDBCI_t;
|
||||
|
||||
@@ -40,7 +36,7 @@ class Commands
|
||||
{
|
||||
|
||||
public:
|
||||
Commands() : m_polIndex(-1) {}
|
||||
Commands() : m_pollIndex(-1) {}
|
||||
~Commands();
|
||||
|
||||
void addCommand(const cmd_t& command);
|
||||
@@ -48,33 +44,36 @@ public:
|
||||
|
||||
std::size_t sizeCmdDB() const { return m_cmdDB.size(); }
|
||||
std::size_t sizeCycDB() const { return m_cycDB.size(); }
|
||||
std::size_t sizePolDB() const { return m_polDB.size(); }
|
||||
std::size_t sizePollDB() const { return m_pollDB.size(); }
|
||||
std::size_t sizeScanDB() const { return m_scanDB.size(); }
|
||||
|
||||
cmd_t const& operator[](const std::size_t& index) const { return m_cmdDB[index]; }
|
||||
|
||||
int findCommand(const std::string& data) const;
|
||||
|
||||
std::string getCmdType(const int index) const { return std::string(m_cmdDB.at(index)[0]); }
|
||||
std::string getEbusCommand(const int index) const;
|
||||
std::string getBusCommand(const int index) const;
|
||||
|
||||
int storeCycData(const std::string& data) const;
|
||||
std::string getCycData(int index) const;
|
||||
|
||||
int nextPolCommand();
|
||||
void storePolData(const std::string& data) const;
|
||||
std::string getPolData(int index) const;
|
||||
int nextPollCommand();
|
||||
void storePollData(const std::string& data) const;
|
||||
std::string getPollData(const int index) const;
|
||||
|
||||
void storeScanData(const std::string& data);
|
||||
std::string getScanData(const int index) const { return m_scanDB[index]; }
|
||||
|
||||
private:
|
||||
cmdDB_t m_cmdDB;
|
||||
map_t m_cycDB;
|
||||
map_t m_polDB;
|
||||
size_t m_polIndex;
|
||||
map_t m_pollDB;
|
||||
size_t m_pollIndex;
|
||||
std::vector<std::string> m_scanDB;
|
||||
|
||||
void printCommand(const cmd_t& command) const;
|
||||
|
||||
};
|
||||
|
||||
|
||||
} //namespace
|
||||
|
||||
#endif // LIBEBUS_COMMANDS_H_
|
||||
|
||||
|
||||
@@ -22,10 +22,6 @@
|
||||
#include <fstream>
|
||||
#include <dirent.h>
|
||||
|
||||
namespace libebus
|
||||
{
|
||||
|
||||
|
||||
void ConfigFileCSV::parse(std::istream& is, Commands& commands)
|
||||
{
|
||||
std::string line;
|
||||
@@ -132,6 +128,3 @@ void ConfigCommands::addFiles(const std::string path, const std::string extensio
|
||||
closedir(dir);
|
||||
};
|
||||
|
||||
|
||||
} //namespace
|
||||
|
||||
|
||||
+16
-18
@@ -24,21 +24,18 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace libebus
|
||||
{
|
||||
|
||||
/** available file endings / types. */
|
||||
enum FileType { CSV, XML };
|
||||
|
||||
/**
|
||||
* @brief Base class for config files.
|
||||
* @brief base class for config files.
|
||||
*/
|
||||
class ConfigFile
|
||||
{
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief Destructor.
|
||||
* @brief destructor.
|
||||
*/
|
||||
virtual ~ConfigFile() {}
|
||||
|
||||
@@ -52,14 +49,14 @@ public:
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Class for CSV config files.
|
||||
* @brief class for CSV config files.
|
||||
*/
|
||||
class ConfigFileCSV : public ConfigFile
|
||||
{
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief Destructor.
|
||||
* @brief destructor.
|
||||
*/
|
||||
~ConfigFileCSV() {}
|
||||
|
||||
@@ -73,14 +70,14 @@ public:
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Class for XML config files.
|
||||
* @brief class for XML config files.
|
||||
*/
|
||||
class ConfigFileXML : public ConfigFile
|
||||
{
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief Destructor.
|
||||
* @brief destructor.
|
||||
*/
|
||||
~ConfigFileXML() {}
|
||||
|
||||
@@ -95,32 +92,32 @@ public:
|
||||
|
||||
|
||||
/**
|
||||
* @brief Class for class Device.
|
||||
* @brief class for class device.
|
||||
*/
|
||||
class ConfigCommands
|
||||
{
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief Set file type and add recursive files from given path.
|
||||
* @brief set file type and add recursive files from given path.
|
||||
* @param path to configuration files.
|
||||
* @param Filetype to parse.
|
||||
* @param filetype to parse.
|
||||
*/
|
||||
ConfigCommands(const std::string path, const FileType type);
|
||||
|
||||
/**
|
||||
* @brief Destructor.
|
||||
* @brief destructor.
|
||||
*/
|
||||
~ConfigCommands() { delete m_configfile; }
|
||||
|
||||
/**
|
||||
* @brief setter for file type.
|
||||
* @param FileType of files.
|
||||
* @param filetype of files.
|
||||
*/
|
||||
void setType(const FileType type);
|
||||
|
||||
/**
|
||||
* @brief Parse files for commands and store them into commands instance.
|
||||
* @brief parse files for commands and store them into commands instance.
|
||||
* @return a commands instance
|
||||
*/
|
||||
Commands* getCommands();
|
||||
@@ -128,10 +125,13 @@ public:
|
||||
private:
|
||||
/** the configfile instance */
|
||||
ConfigFile* m_configfile;
|
||||
|
||||
/** main path for configuration files */
|
||||
std::string m_path;
|
||||
|
||||
/** valid file extension */
|
||||
std::string m_extension;
|
||||
|
||||
/** vector of configuration files */
|
||||
std::vector<std::string> m_files;
|
||||
|
||||
@@ -144,7 +144,5 @@ private:
|
||||
|
||||
};
|
||||
|
||||
|
||||
} //namespace
|
||||
|
||||
#endif // LIBEBUS_CONFIGFILE_H_
|
||||
|
||||
|
||||
Regular → Executable
-7
@@ -29,9 +29,6 @@
|
||||
#include <typeinfo>
|
||||
#include <math.h>
|
||||
|
||||
namespace libebus
|
||||
{
|
||||
|
||||
/** the known data field types. */
|
||||
static const dataType_t dataTypes[] = {
|
||||
{"STR",16*8,bt_str, ADJ, ' ', 1, 16, 0, 0}, // >= 1 byte character string filled up with space
|
||||
@@ -895,7 +892,6 @@ result_t ValueListDataField::writeSymbols(std::istringstream& input,
|
||||
return RESULT_ERR_INVALID_ARG; // value assignment not found
|
||||
}
|
||||
|
||||
|
||||
DataFieldSet::~DataFieldSet()
|
||||
{
|
||||
while (m_fields.empty() == false) {
|
||||
@@ -976,6 +972,3 @@ result_t DataFieldSet::write(std::istringstream& input, SymbolString& masterData
|
||||
|
||||
return RESULT_OK;
|
||||
}
|
||||
|
||||
|
||||
} //namespace
|
||||
|
||||
Regular → Executable
-6
@@ -26,10 +26,6 @@
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
namespace libebus
|
||||
{
|
||||
|
||||
|
||||
/** the message part in which a data field is stored. */
|
||||
enum PartType {
|
||||
pt_template, // special part type for templates (relative offset)
|
||||
@@ -501,6 +497,4 @@ protected:
|
||||
};
|
||||
|
||||
|
||||
} //namespace
|
||||
|
||||
#endif // LIBEBUS_DATA_H_
|
||||
|
||||
@@ -26,10 +26,6 @@
|
||||
#include <vector>
|
||||
#include <cstring>
|
||||
|
||||
namespace libebus
|
||||
{
|
||||
|
||||
|
||||
Decode::Decode(const std::string& data, const std::string& factor)
|
||||
: m_data(data)
|
||||
{
|
||||
@@ -347,6 +343,3 @@ std::string DecodeTTM::decode()
|
||||
return result.str();
|
||||
}
|
||||
|
||||
|
||||
} //namespace
|
||||
|
||||
|
||||
@@ -22,10 +22,6 @@
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace libebus
|
||||
{
|
||||
|
||||
|
||||
class Decode
|
||||
{
|
||||
|
||||
@@ -285,7 +281,4 @@ public:
|
||||
|
||||
};
|
||||
|
||||
|
||||
} //namespace
|
||||
|
||||
#endif // LIBEBUS_DECODE_H_
|
||||
|
||||
@@ -1,73 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) Roland Jax 2012-2014 <ebusd@liwest.at>
|
||||
*
|
||||
* This file is part of ebusd.
|
||||
*
|
||||
* ebusd is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* ebusd is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with ebusd. If not, see http://www.gnu.org/licenses/.
|
||||
*/
|
||||
|
||||
#ifndef LIBEBUS_DUMP_H_
|
||||
#define LIBEBUS_DUMP_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace libebus
|
||||
{
|
||||
|
||||
/**
|
||||
* @brief Class for writing raw bytes to binary file.
|
||||
*/
|
||||
class Dump
|
||||
{
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief Create a new instance to write dump files.
|
||||
* @param filename which will be used for dumping raw bytes.
|
||||
* @param filesize max. Size of the dump file, before switching.
|
||||
*/
|
||||
Dump(std::string filename, long filesize)
|
||||
: m_filename(filename), m_filesize(filesize) {}
|
||||
|
||||
/**
|
||||
* @brief write byte to dump file.
|
||||
* @param byte to write
|
||||
* @return -1 if dump file cannot opened or renaming of dump file failed.
|
||||
*/
|
||||
int write(const char* byte);
|
||||
|
||||
/**
|
||||
* @brief setter for dump file name.
|
||||
* @param filename which will be used for dumping raw bytes.
|
||||
*/
|
||||
void setFilename(const std::string& filename) { m_filename = filename; }
|
||||
|
||||
/**
|
||||
* @brief setter for max size of dump file.
|
||||
* @param filesize max. Size of the dump file, before switching.
|
||||
*/
|
||||
void setFilesize(const long filesize) { m_filesize = filesize; }
|
||||
|
||||
private:
|
||||
/** the name of dump file*/
|
||||
std::string m_filename;
|
||||
/** max. size of dump file */
|
||||
long m_filesize;
|
||||
|
||||
};
|
||||
|
||||
|
||||
} //namespace
|
||||
|
||||
#endif // LIBEBUS_DUMP_H_
|
||||
@@ -26,10 +26,6 @@
|
||||
#include <vector>
|
||||
#include <cstring>
|
||||
|
||||
namespace libebus
|
||||
{
|
||||
|
||||
|
||||
Encode::Encode(const std::string& data, const std::string& factor)
|
||||
: m_data(data)
|
||||
{
|
||||
@@ -364,6 +360,3 @@ std::string EncodeTTM::encode()
|
||||
return result.str();
|
||||
}
|
||||
|
||||
|
||||
} //namespace
|
||||
|
||||
|
||||
@@ -22,10 +22,6 @@
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace libebus
|
||||
{
|
||||
|
||||
|
||||
class Encode
|
||||
{
|
||||
|
||||
@@ -285,7 +281,4 @@ public:
|
||||
|
||||
};
|
||||
|
||||
|
||||
} //namespace
|
||||
|
||||
#endif // LIBEBUS_ENCODE_H_
|
||||
|
||||
+14
-22
@@ -20,19 +20,11 @@
|
||||
#include "port.h"
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <termios.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
#include <unistd.h>
|
||||
|
||||
|
||||
namespace libebus
|
||||
{
|
||||
|
||||
#include <poll.h>
|
||||
|
||||
bool Device::isOpen()
|
||||
{
|
||||
@@ -72,18 +64,23 @@ ssize_t Device::recvBytes(const long timeout, size_t maxCount)
|
||||
return -1; // TODO RESULT_ERR_DEVICE
|
||||
|
||||
if (timeout > 0) {
|
||||
fd_set readfds;
|
||||
struct timeval tdiff;
|
||||
int ret, nfds = 1;
|
||||
struct pollfd fds[nfds];
|
||||
struct timespec tdiff;
|
||||
|
||||
// set select timeout
|
||||
tdiff.tv_sec = 0;
|
||||
tdiff.tv_usec = timeout;
|
||||
tdiff.tv_nsec = timeout*1000;
|
||||
|
||||
FD_ZERO(&readfds);
|
||||
FD_SET(m_fd, &readfds);
|
||||
memset(fds, 0, sizeof(fds));
|
||||
|
||||
if (select(m_fd + 1, &readfds, NULL, NULL, &tdiff) != 1)
|
||||
return -2; // TODO RESULT_ERR_TIMEOUT
|
||||
fds[0].fd = m_fd;
|
||||
fds[0].events = POLLIN;
|
||||
|
||||
ret = ppoll(fds, nfds, &tdiff, NULL);
|
||||
|
||||
if (ret == -1) return -1; // TODO RESULT_ERR_DEVICE
|
||||
if (ret == 0) return -2; // TODO RESULT_ERR_TIMEOUT
|
||||
}
|
||||
|
||||
if (maxCount > sizeof(m_buffer))
|
||||
@@ -141,7 +138,7 @@ void DeviceSerial::openDevice(const std::string deviceName, const bool noDeviceC
|
||||
newSettings.c_cc[VTIME] = 0;
|
||||
|
||||
// empty device buffer
|
||||
tcflush(m_fd, TCIOFLUSH);
|
||||
tcflush(m_fd, TCIFLUSH);
|
||||
|
||||
// activate new settings of serial device
|
||||
tcsetattr(m_fd, TCSANOW, &newSettings);
|
||||
@@ -255,8 +252,3 @@ void Port::setType(const DeviceType type)
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
} //namespace
|
||||
|
||||
|
||||
|
||||
|
||||
+18
-18
@@ -25,9 +25,6 @@
|
||||
#include <termios.h>
|
||||
#include <unistd.h>
|
||||
|
||||
namespace libebus
|
||||
{
|
||||
|
||||
/** available device types. */
|
||||
enum DeviceType { SERIAL, NETWORK };
|
||||
|
||||
@@ -39,19 +36,19 @@ enum DeviceType { SERIAL, NETWORK };
|
||||
|
||||
|
||||
/**
|
||||
* @brief Base class for input devices.
|
||||
* @brief base class for input devices.
|
||||
*/
|
||||
class Device
|
||||
{
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief Constructs a new instance.
|
||||
* @brief constructs a new instance.
|
||||
*/
|
||||
Device() : m_fd(-1), m_open(false), m_noDeviceCheck(false) {}
|
||||
|
||||
/**
|
||||
* @brief Destructor.
|
||||
* @brief destructor.
|
||||
*/
|
||||
virtual ~Device() {}
|
||||
|
||||
@@ -74,7 +71,7 @@ public:
|
||||
bool isOpen();
|
||||
|
||||
/**
|
||||
* @brief sendBytes write bytes into opened file descriptor.
|
||||
* @brief sendBytes write bytes to opened file descriptor.
|
||||
* @param buffer data to send.
|
||||
* @param nbytes number of bytes to send.
|
||||
* @return number of written bytes or -1 if an error has occured.
|
||||
@@ -83,7 +80,7 @@ public:
|
||||
|
||||
/**
|
||||
* @brief recvBytes read bytes from opened file descriptor.
|
||||
* @param timeout max time out for new input data.
|
||||
* @param timeoutmax time for new input data [usec].
|
||||
* @param maxCount max size of receive buffer.
|
||||
* @return number of read bytes or -1 if an error has occured.
|
||||
*/
|
||||
@@ -104,12 +101,16 @@ public:
|
||||
protected:
|
||||
/** if of file descriptor */
|
||||
int m_fd;
|
||||
|
||||
/** state of device*/
|
||||
bool m_open;
|
||||
|
||||
/** state of device check */
|
||||
bool m_noDeviceCheck;
|
||||
|
||||
/** queue for received bytes */
|
||||
std::queue<unsigned char> m_recvBuffer;
|
||||
|
||||
/** receive buffer */
|
||||
unsigned char m_buffer[MAX_READ_SIZE];
|
||||
|
||||
@@ -123,14 +124,14 @@ private:
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Class for serial input device.
|
||||
* @brief class for serial input device.
|
||||
*/
|
||||
class DeviceSerial : public Device
|
||||
{
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief Destructor.
|
||||
* @brief destructor.
|
||||
*/
|
||||
~DeviceSerial() { closeDevice(); }
|
||||
|
||||
@@ -153,14 +154,14 @@ private:
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Class for network input device.
|
||||
* @brief class for network input device.
|
||||
*/
|
||||
class DeviceNetwork : public Device
|
||||
{
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief Destructor.
|
||||
* @brief destructor.
|
||||
*/
|
||||
~DeviceNetwork() { closeDevice(); }
|
||||
|
||||
@@ -181,21 +182,21 @@ private:
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Wrapper class for class Device.
|
||||
* @brief wrapper class for class device.
|
||||
*/
|
||||
class Port
|
||||
{
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief Constructs a new instance and determine device type.
|
||||
* @brief constructs a new instance and determine device type.
|
||||
* @param deviceName to determine device type.
|
||||
* @param noDeviceCheck en-/disable device check.
|
||||
*/
|
||||
Port(const std::string deviceName, const bool noDeviceCheck);
|
||||
|
||||
/**
|
||||
* @brief Destructor.
|
||||
* @brief destructor.
|
||||
*/
|
||||
~Port() { delete m_device; }
|
||||
|
||||
@@ -248,8 +249,10 @@ public:
|
||||
private:
|
||||
/** the device name */
|
||||
std::string m_deviceName;
|
||||
|
||||
/** the device instance */
|
||||
Device* m_device;
|
||||
|
||||
/** true if device check is disabled */
|
||||
bool m_noDeviceCheck;
|
||||
|
||||
@@ -261,7 +264,4 @@ private:
|
||||
|
||||
};
|
||||
|
||||
|
||||
} //namespace
|
||||
|
||||
#endif // LIBEBUS_PORT_H_
|
||||
|
||||
@@ -19,10 +19,7 @@
|
||||
|
||||
#include "result.h"
|
||||
|
||||
namespace libebus
|
||||
{
|
||||
|
||||
const char* getResultCodeCStr(result_t resultCode) {
|
||||
const char* getResultCode(result_t resultCode) {
|
||||
switch (resultCode) {
|
||||
case RESULT_ERR_SEND: return "ERR_SEND: send error";
|
||||
case RESULT_ERR_EXTRA_DATA: return "ERR_EXTRA_DATA: received bytes > sent bytes";
|
||||
@@ -43,5 +40,3 @@ const char* getResultCodeCStr(result_t resultCode) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} //namespace
|
||||
|
||||
@@ -20,10 +20,6 @@
|
||||
#ifndef LIBEBUS_RESULT_H_
|
||||
#define LIBEBUS_RESULT_H_
|
||||
|
||||
namespace libebus
|
||||
{
|
||||
|
||||
|
||||
static const int RESULT_OK = 0;
|
||||
|
||||
static const int RESULT_BUS_ACQUIRED = 1; // bus successfully acquired
|
||||
@@ -54,9 +50,6 @@ typedef int result_t;
|
||||
* @param resultCode the result code (see RESULT_ constants).
|
||||
* @return the string corresponding to the result code.
|
||||
*/
|
||||
const char* getResultCodeCStr(result_t resultCode);
|
||||
|
||||
|
||||
} //namespace
|
||||
const char* getResultCode(result_t resultCode);
|
||||
|
||||
#endif // LIBEBUS_RESULT_H_
|
||||
|
||||
@@ -22,9 +22,6 @@
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
|
||||
namespace libebus
|
||||
{
|
||||
|
||||
/**
|
||||
* @brief CRC8 lookup table for the polynom 0x9b = x^8 + x^7 + x^4 + x^3 + x^1 + 1.
|
||||
*/
|
||||
@@ -190,4 +187,3 @@ bool isMaster(unsigned char addr) {
|
||||
&& ((addrLo == 0x0) || (addrLo == 0x1) || (addrLo == 0x3) || (addrLo == 0x7) || (addrLo == 0xF));
|
||||
}
|
||||
|
||||
} //namespace
|
||||
|
||||
@@ -25,10 +25,6 @@
|
||||
#include <sstream>
|
||||
#include <queue>
|
||||
|
||||
namespace libebus
|
||||
{
|
||||
|
||||
|
||||
static const unsigned char ESC = 0xA9; // escape symbol, either followed by 0x00 for the value 0xA9, or 0x01 for the value 0xAA
|
||||
static const unsigned char SYN = 0xAA; // synchronization symbol
|
||||
static const unsigned char ACK = 0x00; // positive acknowledge
|
||||
@@ -139,7 +135,4 @@ private:
|
||||
*/
|
||||
bool isMaster(unsigned char addr);
|
||||
|
||||
|
||||
} //namespace
|
||||
|
||||
#endif // LIBEBUS_SYMBOL_H_
|
||||
|
||||
@@ -25,8 +25,6 @@
|
||||
#include <sstream>
|
||||
#include <vector>
|
||||
|
||||
using namespace libebus;
|
||||
|
||||
// will be part of cfg csv class
|
||||
void readCSV(std::istream& is, Commands& commands){
|
||||
std::string line;
|
||||
|
||||
@@ -24,9 +24,6 @@
|
||||
#include <sstream>
|
||||
#include <vector>
|
||||
|
||||
using namespace libebus;
|
||||
|
||||
|
||||
int main() {
|
||||
|
||||
std::string dir("test");
|
||||
|
||||
Regular → Executable
+3
-5
@@ -21,8 +21,6 @@
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
|
||||
using namespace libebus;
|
||||
|
||||
void verify(bool expectFailMatch, std::string type, std::string input,
|
||||
bool match, std::string expectStr, std::string gotStr)
|
||||
{
|
||||
@@ -217,7 +215,7 @@ int main()
|
||||
|
||||
if (result != RESULT_OK) {
|
||||
std::cout << "\"" << check[0] << "\": create error: "
|
||||
<< getResultCodeCStr(result) << std::endl;
|
||||
<< getResultCode(result) << std::endl;
|
||||
continue;
|
||||
}
|
||||
if (fields == NULL) {
|
||||
@@ -256,7 +254,7 @@ int main()
|
||||
<< check[2] << "< OK" << std::endl;
|
||||
else if (result != RESULT_OK) {
|
||||
std::cout << " read " << fields->getName() << " >" << check[2] << "< error: "
|
||||
<< getResultCodeCStr(result) << std::endl;
|
||||
<< getResultCode(result) << std::endl;
|
||||
}
|
||||
else {
|
||||
bool match = strcasecmp(output.str().c_str(), expectStr.c_str()) == 0;
|
||||
@@ -276,7 +274,7 @@ int main()
|
||||
}
|
||||
else if (result != RESULT_OK) {
|
||||
std::cout << " write " << fields->getName() << " >"
|
||||
<< expectStr << "< error: " << getResultCodeCStr(result) << std::endl;
|
||||
<< expectStr << "< error: " << getResultCode(result) << std::endl;
|
||||
}
|
||||
else {
|
||||
bool match = mstr == writeMstr && sstr == writeSstr;
|
||||
|
||||
@@ -21,10 +21,6 @@
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
|
||||
|
||||
using namespace libebus;
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
Decode* help_dec = NULL;
|
||||
|
||||
@@ -21,10 +21,6 @@
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
|
||||
|
||||
using namespace libebus;
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
Encode* help_enc = NULL;
|
||||
|
||||
@@ -21,8 +21,6 @@
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
|
||||
using namespace libebus;
|
||||
|
||||
int main ()
|
||||
{
|
||||
std::string dev("/dev/ttyUSB20");
|
||||
|
||||
@@ -21,8 +21,6 @@
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
|
||||
using namespace libebus;
|
||||
|
||||
int main ()
|
||||
{
|
||||
SymbolString sstr = SymbolString("10feb5050427a915aa");
|
||||
|
||||
@@ -4,18 +4,20 @@ AM_CXXFLAGS = -fpic \
|
||||
|
||||
noinst_LIBRARIES = libutils.a
|
||||
|
||||
libutils_a_SOURCES = wqueue.h \
|
||||
notify.h \
|
||||
appl.cpp \
|
||||
libutils_a_SOURCES = appl.cpp \
|
||||
appl.h \
|
||||
daemon.cpp \
|
||||
daemon.h \
|
||||
logger.cpp \
|
||||
logger.h \
|
||||
notify.cpp \
|
||||
notify.h \
|
||||
tcpsocket.cpp \
|
||||
tcpsocket.h \
|
||||
thread.cpp \
|
||||
thread.h \
|
||||
tcpsocket.cpp \
|
||||
tcpsocket.h
|
||||
wqueue.h
|
||||
|
||||
|
||||
distclean-local:
|
||||
-rm -f Makefile.in
|
||||
|
||||
+150
-121
@@ -22,200 +22,229 @@
|
||||
#include <iomanip>
|
||||
#include <cstdlib>
|
||||
|
||||
Appl& Appl::Instance()
|
||||
Appl& Appl::Instance(const bool command)
|
||||
{
|
||||
static Appl instance;
|
||||
static Appl instance(command);
|
||||
return instance;
|
||||
}
|
||||
|
||||
Appl::~Appl()
|
||||
{
|
||||
m_args.clear();
|
||||
m_params.clear();
|
||||
m_opts.clear();
|
||||
m_optvals.clear();
|
||||
}
|
||||
|
||||
void Appl::addArgs(const std::string argTxt, const int argNum)
|
||||
void Appl::addText(const char* text)
|
||||
{
|
||||
m_argTxt = argTxt;
|
||||
m_argNum = argNum;
|
||||
opt_t opt;
|
||||
opt.name = "__text_only__";
|
||||
opt.shortname = "";
|
||||
opt.datatype = dt_none;
|
||||
opt.optiontype = ot_none;
|
||||
opt.description = text;
|
||||
m_opts.push_back(opt);
|
||||
}
|
||||
|
||||
void Appl::addItem(const char* name, Param param, const char* shortname,
|
||||
const char* longname, const char* description,
|
||||
Datatype datatype, Optiontype optiontype)
|
||||
void Appl::addOption(const char* name, const char* shortname, OptVal optval,
|
||||
DataType datatype, OptionType optiontype, const char* description)
|
||||
{
|
||||
if (strlen(name) != 0)
|
||||
m_params[name] = param;
|
||||
if (strlen(name) != 0) {
|
||||
|
||||
if (strlen(longname) != 0) {
|
||||
Arg arg;
|
||||
arg.name = name;
|
||||
arg.shortname = shortname;
|
||||
arg.longname = longname;
|
||||
arg.description = description;
|
||||
arg.datatype = datatype;
|
||||
arg.optiontype = optiontype;
|
||||
m_args.push_back(arg);
|
||||
m_optvals[name] = optval;
|
||||
|
||||
opt_t opt;
|
||||
opt.name = name;
|
||||
opt.shortname = shortname;
|
||||
opt.datatype = datatype;
|
||||
opt.optiontype = optiontype;
|
||||
opt.description = description;
|
||||
m_opts.push_back(opt);
|
||||
}
|
||||
}
|
||||
|
||||
void Appl::printArgs()
|
||||
{
|
||||
std::cerr << std::endl << "Usage:" << std::endl << " "
|
||||
<< m_argv[0].substr(m_argv[0].find_last_of("/\\") + 1) << " [OPTIONS...]" ;
|
||||
|
||||
if (m_argTxt.size() != 0)
|
||||
std::cerr << " " << m_argTxt;
|
||||
|
||||
std::cerr << std::endl << std::endl << "Options:" << std::endl << std::endl;
|
||||
|
||||
for (a_it = m_args.begin(); a_it < m_args.end(); a_it++) {
|
||||
const char* c = (strlen(a_it->shortname) == 1) ? a_it->shortname : " ";
|
||||
std::cerr << ((strcmp(c, " ") == 0) ? " " : "-") << c
|
||||
<< " | --" << a_it->longname
|
||||
<< "\t" << a_it->description
|
||||
<< std::endl;
|
||||
}
|
||||
|
||||
std::cerr << std::endl;
|
||||
}
|
||||
|
||||
bool Appl::parseArgs(int argc, char* argv[])
|
||||
void Appl::parseArgs(int argc, char* argv[])
|
||||
{
|
||||
std::vector<std::string> _argv(argv, argv + argc);
|
||||
m_argc = argc;
|
||||
m_argv = _argv;
|
||||
|
||||
for (size_t i = 1; i < m_argc; i++) {
|
||||
// walk through all arguments
|
||||
for (int i = 1; i < argc; i++) {
|
||||
|
||||
// find option with long format '--'
|
||||
if (m_argv[i].rfind("--") == 0 && m_argv[i].size() > 2) {
|
||||
if (_argv[i].rfind("--") == 0 && _argv[i].size() > 2) {
|
||||
|
||||
// is next item an added argument?
|
||||
if (i+1 < m_argc && m_argv[i+1].rfind("-", 0) == std::string::npos) {
|
||||
if (checkArg(m_argv[i].substr(2), m_argv[i+1]) == false)
|
||||
return false;
|
||||
} else {
|
||||
if (checkArg(m_argv[i].substr(2), "") == false)
|
||||
return false;
|
||||
if (i+1 < argc && _argv[i+1].rfind("-", 0) == std::string::npos) {
|
||||
if (checkOption(_argv[i].substr(2), _argv[i+1]) == false)
|
||||
printHelp();
|
||||
}
|
||||
else {
|
||||
if (checkOption(_argv[i].substr(2), "") == false)
|
||||
printHelp();
|
||||
}
|
||||
|
||||
// find option with short format '-'
|
||||
} else if (m_argv[i].rfind("-") == 0 && m_argv[i].size() > 1) {
|
||||
} else if (_argv[i].rfind("-") == 0 && _argv[i].size() > 1) {
|
||||
|
||||
// walk through all characters
|
||||
for (size_t j = 1; j < m_argv[i].size(); j++) {
|
||||
for (size_t j = 1; j < _argv[i].size(); j++) {
|
||||
|
||||
// only last charater could have an argument
|
||||
if (i+1 < m_argc && m_argv[i+1].rfind("-", 0) == std::string::npos
|
||||
&& j+1 == m_argv[i].size()) {
|
||||
if (checkArg(m_argv[i].substr(j,1), m_argv[i+1]) == false)
|
||||
return false;
|
||||
} else {
|
||||
if (checkArg(m_argv[i].substr(j,1), "") == false)
|
||||
return false;
|
||||
if (i+1 < argc && _argv[i+1].rfind("-", 0) == std::string::npos
|
||||
&& j+1 == _argv[i].size()) {
|
||||
if (checkOption(_argv[i].substr(j,1), _argv[i+1]) == false)
|
||||
printHelp();
|
||||
}
|
||||
else {
|
||||
if (checkOption(_argv[i].substr(j,1), "") == false)
|
||||
printHelp();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// check args
|
||||
if (m_argNum > 0) {
|
||||
if (m_argc < (m_argNum + 1))
|
||||
return false;
|
||||
// check command
|
||||
if (m_needCommand == true) {
|
||||
for (int i = 1; i < argc; i++) {
|
||||
|
||||
for (size_t i = 1; i < m_argc; i++) {
|
||||
|
||||
if (m_argv[i].rfind("-", 0) != std::string::npos) {
|
||||
if (_argv[i].rfind("-", 0) != std::string::npos) {
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
m_argValues.push_back(m_argv[i]);
|
||||
m_arguments.push_back(_argv[i]);
|
||||
}
|
||||
|
||||
if (m_argValues.size() < m_argNum)
|
||||
return false;
|
||||
if (m_arguments.size() == 0) {
|
||||
std::cerr << std::endl << "command needed" << std::endl;
|
||||
printHelp();
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Appl::printSettings()
|
||||
bool Appl::checkOption(const std::string& option, const std::string& value)
|
||||
{
|
||||
std::cerr << std::endl << "Settings:" << std::endl;
|
||||
if (strcmp(option.c_str(), "settings") == 0)
|
||||
printSettings();
|
||||
|
||||
for (a_it = m_args.begin(); a_it < m_args.end(); a_it++) {
|
||||
const char* c = (strlen(a_it->shortname) == 1) ? a_it->shortname : " ";
|
||||
std::cerr << ((strcmp(c, " ") == 0) ? " " : "-") << c
|
||||
<< " | --" << a_it->longname
|
||||
<< " = ";
|
||||
if (a_it->datatype == type_bool) {
|
||||
if (getParam<bool>(a_it->name) == true)
|
||||
std::cerr << "yes" << std::endl;
|
||||
else
|
||||
std::cerr << "no" << std::endl;
|
||||
}
|
||||
else if (a_it->datatype == type_int) {
|
||||
std::cerr << getParam<int>(a_it->name) << std::endl;
|
||||
}
|
||||
else if (a_it->datatype == type_long) {
|
||||
std::cerr << getParam<long>(a_it->name) << std::endl;
|
||||
}
|
||||
else if (a_it->datatype == type_float) {
|
||||
std::cerr << getParam<float>(a_it->name) << std::endl;
|
||||
}
|
||||
else if (a_it->datatype == type_string) {
|
||||
std::cerr << getParam<const char*>(a_it->name) << std::endl;
|
||||
}
|
||||
if (strcmp(option.c_str(), "v") == 0 || strcmp(option.c_str(), "version") == 0)
|
||||
printVersion();
|
||||
|
||||
}
|
||||
if (strcmp(option.c_str(), "h") == 0 || strcmp(option.c_str(), "help") == 0)
|
||||
printHelp();
|
||||
|
||||
std::cerr << std::endl;
|
||||
}
|
||||
for (o_it = m_opts.begin(); o_it < m_opts.end(); o_it++) {
|
||||
if (o_it->shortname == option || o_it->name == option) {
|
||||
|
||||
bool Appl::checkArg(const std::string& name, const std::string& arg)
|
||||
{
|
||||
for (a_it = m_args.begin(); a_it < m_args.end(); a_it++) {
|
||||
if (a_it->shortname == name || a_it->longname == name) {
|
||||
if (a_it->optiontype == opt_mandatory && arg.size() == 0) {
|
||||
// need this option and argument?
|
||||
if (o_it->optiontype == ot_mandatory && value.size() == 0) {
|
||||
std::cerr << std::endl << "option requires an argument '"
|
||||
<< name << "'" << std::endl;
|
||||
<< option << "'" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((a_it->optiontype == opt_optional && arg.size() != 0)
|
||||
|| a_it->optiontype != opt_optional)
|
||||
addParam(a_it->name, arg, a_it->datatype);
|
||||
// add given value to option
|
||||
if ((o_it->optiontype == ot_optional && value.size() != 0)
|
||||
|| o_it->optiontype != ot_optional)
|
||||
setOptVal(o_it->name, value, o_it->datatype);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
std::cerr << m_argv[0].substr(2) << ": Unknown Option -- " << name << std::endl;
|
||||
std::cerr << std::endl << "unknown option '" << option << "'" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
void Appl::addParam(const char* name, const std::string arg, Datatype datatype)
|
||||
void Appl::setOptVal(const char* option, const std::string value, DataType datatype)
|
||||
{
|
||||
switch (datatype) {
|
||||
case type_bool:
|
||||
m_params[name] = true;
|
||||
case dt_bool:
|
||||
m_optvals[option] = true;
|
||||
break;
|
||||
case type_int:
|
||||
m_params[name] = strtol(arg.c_str(), NULL, 10);
|
||||
case dt_int:
|
||||
m_optvals[option] = strtol(value.c_str(), NULL, 10);
|
||||
break;
|
||||
case type_long:
|
||||
m_params[name] = strtol(arg.c_str(), NULL, 10);
|
||||
case dt_long:
|
||||
m_optvals[option] = strtol(value.c_str(), NULL, 10);
|
||||
break;
|
||||
case type_float:
|
||||
m_params[name] = static_cast<float>(strtod(arg.c_str(), NULL));
|
||||
case dt_float:
|
||||
m_optvals[option] = static_cast<float>(strtod(value.c_str(), NULL));
|
||||
break;
|
||||
case type_string:
|
||||
m_params[name] = arg.c_str();
|
||||
case dt_string:
|
||||
m_optvals[option] = value.c_str();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Appl::printVersion()
|
||||
{
|
||||
std::cerr << m_version << std::endl;
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
void Appl::printHelp()
|
||||
{
|
||||
std::cerr << std::endl << "Usage:" << std::endl << " "
|
||||
<< m_argv[0].substr(m_argv[0].find_last_of("/\\") + 1) << " [OPTIONS...]" ;
|
||||
|
||||
if (m_needCommand == true)
|
||||
std::cerr << " COMMAND {ARGS...}" << std::endl << std::endl;
|
||||
else
|
||||
std::cerr << std::endl << std::endl;
|
||||
|
||||
for (o_it = m_opts.begin(); o_it < m_opts.end(); o_it++) {
|
||||
if (strcmp(o_it->name, "__text_only__") == 0)
|
||||
std::cerr << o_it->description << std::endl;
|
||||
else {
|
||||
const char* c = (strlen(o_it->shortname) == 1) ? o_it->shortname : " ";
|
||||
std::cerr << ((strcmp(c, " ") == 0) ? " " : "-") << c
|
||||
<< " | --" << o_it->name
|
||||
<< "\t" << o_it->description
|
||||
<< std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
std::cerr << " | --settings\n-v | --version\n-h | --help" << std::endl << std::endl;
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
void Appl::printSettings()
|
||||
{
|
||||
std::cerr << std::endl << "Settings:" << std::endl << std::endl;
|
||||
|
||||
for (o_it = m_opts.begin(); o_it < m_opts.end(); o_it++) {
|
||||
if (strcmp(o_it->name, "__text_only__") == 0)
|
||||
continue;
|
||||
|
||||
const char* c = (strlen(o_it->shortname) == 1) ? o_it->shortname : " ";
|
||||
std::cerr << ((strcmp(c, " ") == 0) ? " " : "-") << c
|
||||
<< " | --" << o_it->name
|
||||
<< " = ";
|
||||
if (o_it->datatype == dt_bool) {
|
||||
if (getOptVal<bool>(o_it->name) == true)
|
||||
std::cerr << "yes" << std::endl;
|
||||
else
|
||||
std::cerr << "no" << std::endl;
|
||||
}
|
||||
else if (o_it->datatype == dt_int) {
|
||||
std::cerr << getOptVal<int>(o_it->name) << std::endl;
|
||||
}
|
||||
else if (o_it->datatype == dt_long) {
|
||||
std::cerr << getOptVal<long>(o_it->name) << std::endl;
|
||||
}
|
||||
else if (o_it->datatype == dt_float) {
|
||||
std::cerr << getOptVal<float>(o_it->name) << std::endl;
|
||||
}
|
||||
else if (o_it->datatype == dt_string) {
|
||||
std::cerr << getOptVal<const char*>(o_it->name) << std::endl;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
std::cerr << std::endl;
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
+153
-62
@@ -17,96 +17,187 @@
|
||||
* along with ebusd. If not, see http://www.gnu.org/licenses/.
|
||||
*/
|
||||
|
||||
#ifndef LIBCORE_APPL_H_
|
||||
#define LIBCORE_APPL_H_
|
||||
#ifndef LIBUTILS_APPL_H_
|
||||
#define LIBUTILS_APPL_H_
|
||||
|
||||
#include <string>
|
||||
#include <cstring>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
/** the available data types. */
|
||||
enum DataType {
|
||||
dt_none, // default value
|
||||
dt_bool, //
|
||||
dt_int, //
|
||||
dt_long, //
|
||||
dt_float, //
|
||||
dt_string, //
|
||||
};
|
||||
|
||||
/** option types. */
|
||||
enum OptionType {
|
||||
ot_none, // default value
|
||||
ot_optional, // a value is optional
|
||||
ot_mandatory, // a value is mandatory
|
||||
};
|
||||
|
||||
/** structure for defining application options */
|
||||
typedef struct opt {
|
||||
const char* name;
|
||||
const char* shortname;
|
||||
const char* description;
|
||||
DataType datatype;
|
||||
OptionType optiontype;
|
||||
} opt_t;
|
||||
|
||||
/** union for option values */
|
||||
union OptVal {
|
||||
bool b;
|
||||
int i;
|
||||
long l;
|
||||
float f;
|
||||
const char* c;
|
||||
|
||||
OptVal() { memset(this, 0, sizeof(OptVal)); }
|
||||
OptVal(bool _b) : b(_b) {}
|
||||
OptVal(int _i) : i(_i) {}
|
||||
OptVal(long _l) : l(_l) {}
|
||||
OptVal(float _f) : f(_f) {}
|
||||
OptVal(const char* _c) : c(_c) {}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @brief class for all kinds of application parameters.
|
||||
*/
|
||||
class Appl
|
||||
{
|
||||
|
||||
private:
|
||||
struct Option;
|
||||
|
||||
public:
|
||||
enum Datatype { type_none, type_bool, type_int, type_long, type_float, type_string };
|
||||
enum Optiontype { opt_none, opt_optional, opt_mandatory };
|
||||
|
||||
union Param {
|
||||
bool b;
|
||||
int i;
|
||||
long l;
|
||||
float f;
|
||||
const char* c;
|
||||
|
||||
Param() { memset(this, 0, sizeof(Param)); }
|
||||
Param(bool _b) : b(_b) {}
|
||||
Param(int _i) : i(_i) {}
|
||||
Param(long _l) : l(_l) {}
|
||||
Param(float _f) : f(_f) {}
|
||||
Param(const char* _c) : c(_c) {}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
T getParam(const char* name)
|
||||
{
|
||||
p_it = m_params.find(name);
|
||||
return (reinterpret_cast<T&>(p_it->second));
|
||||
}
|
||||
|
||||
static Appl& Instance();
|
||||
/**
|
||||
* @brief create an instance and return the reference.
|
||||
* @param command is true if an command is needed.
|
||||
* @return the reference to instance.
|
||||
*/
|
||||
static Appl& Instance(const bool command=false);
|
||||
|
||||
/**
|
||||
* @brief destructor.
|
||||
*/
|
||||
~Appl();
|
||||
|
||||
void addArgs(const std::string argTxt, const int argNum);
|
||||
size_t numArg() const { return m_argValues.size(); }
|
||||
std::string getArg(const int argNum) const { return m_argValues[argNum]; }
|
||||
/**
|
||||
* @brief save application version string.
|
||||
* @param version string.
|
||||
*/
|
||||
void setVersion(const char* version) { m_version = version; }
|
||||
|
||||
void addItem(const char* name, Param param, const char* shortname,
|
||||
const char* longname, const char* description,
|
||||
Datatype datatype, Optiontype optiontype);
|
||||
/**
|
||||
* @brief create new entry of application option only for help page.
|
||||
* @param text string to print.
|
||||
*/
|
||||
void addText(const char* text);
|
||||
|
||||
void printArgs();
|
||||
/**
|
||||
* @brief create new entry of application option.
|
||||
* @param name the long name.
|
||||
* @param shortname optional short name.
|
||||
* @param optval value of option.
|
||||
* @param datatype data type of option value.
|
||||
* @param optiontype type of given option.
|
||||
* @param description hint text for help page.
|
||||
*/
|
||||
void addOption(const char* name, const char* shortname, OptVal optval,
|
||||
DataType datatype, OptionType optiontype, const char* description);
|
||||
|
||||
bool parseArgs(int argc, char* argv[]);
|
||||
void printSettings();
|
||||
/**
|
||||
* @brief returns the value of the interested option.
|
||||
* @param name the interested option.
|
||||
* @return casted value.
|
||||
*/
|
||||
template <typename T>
|
||||
T getOptVal(const char* name)
|
||||
{
|
||||
ov_it = m_optvals.find(name);
|
||||
return (reinterpret_cast<T&>(ov_it->second));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief parse application arguments.
|
||||
* @param argc the number of options.
|
||||
* @param argv the given options.
|
||||
*/
|
||||
void parseArgs(int argc, char* argv[]);
|
||||
|
||||
/**
|
||||
* @brief returns the number of saved commands and arguments.
|
||||
* @return number of commands and arguments.
|
||||
*/
|
||||
int numArgs() const { return m_arguments.size(); }
|
||||
|
||||
/**
|
||||
* @brief returns the string of an interested argument (0 = command).
|
||||
* @param num number of interested argument.
|
||||
* @return string value.
|
||||
*/
|
||||
std::string getArg(const int num) const { return m_arguments[num]; }
|
||||
|
||||
private:
|
||||
Appl() {}
|
||||
/** private constructor - singleton pattern */
|
||||
Appl(const bool command) : m_needCommand(command) {}
|
||||
Appl(const Appl&);
|
||||
Appl& operator= (const Appl&);
|
||||
Appl& operator=(const Appl&);
|
||||
|
||||
struct Arg {
|
||||
const char* name;
|
||||
const char* shortname;
|
||||
const char* longname;
|
||||
const char* description;
|
||||
Datatype datatype;
|
||||
Optiontype optiontype;
|
||||
};
|
||||
/** application options */
|
||||
std::vector<opt_t> m_opts;
|
||||
std::vector<opt_t>::const_iterator o_it;
|
||||
|
||||
size_t m_argc;
|
||||
/** map option - value */
|
||||
std::map<const char*, OptVal> m_optvals;
|
||||
std::map<const char*, OptVal>::iterator ov_it;
|
||||
|
||||
/** given arguments */
|
||||
std::vector<std::string> m_argv;
|
||||
|
||||
std::vector<Arg> m_args;
|
||||
std::vector<Arg>::const_iterator a_it;
|
||||
/** application version string */
|
||||
const char* m_version;
|
||||
|
||||
std::map<const char*, Param> m_params;
|
||||
std::map<const char*, Param>::iterator p_it;
|
||||
/** true if the application need a command */
|
||||
bool m_needCommand;
|
||||
|
||||
std::string m_argTxt;
|
||||
size_t m_argNum;
|
||||
/** arguments (argument 0 = command) string */
|
||||
std::vector<std::string> m_arguments;
|
||||
|
||||
std::vector<std::string> m_argValues;
|
||||
/**
|
||||
* @brief checks the passed parameter if this is a valid option.
|
||||
* @param option to check.
|
||||
* @param value to save if paramter is a valid option.
|
||||
*/
|
||||
bool checkOption(const std::string& option, const std::string& value);
|
||||
|
||||
bool checkArg(const std::string& name, const std::string& arg);
|
||||
/**
|
||||
* @brief save the passed value to option.
|
||||
* @param option name.
|
||||
* @param value to save.
|
||||
* @param datatype of given option.
|
||||
*/
|
||||
void setOptVal(const char* option, const std::string value, DataType datatype);
|
||||
|
||||
void addParam(const char* name, Param param) { m_params[name] = param; }
|
||||
/**
|
||||
* @brief print application version.
|
||||
*/
|
||||
void printVersion();
|
||||
|
||||
void addParam(const char* name, const std::string arg, Datatype datatype);
|
||||
/**
|
||||
* @brief print help page.
|
||||
*/
|
||||
void printHelp();
|
||||
|
||||
/**
|
||||
* @brief print used option settings.
|
||||
*/
|
||||
void printSettings();
|
||||
};
|
||||
|
||||
#endif // LIBCORE_APPL_H_
|
||||
#endif // LIBUTILS_APPL_H_
|
||||
|
||||
@@ -32,10 +32,10 @@ Daemon& Daemon::Instance()
|
||||
return instance;
|
||||
}
|
||||
|
||||
void Daemon::run(const char* file)
|
||||
void Daemon::run(const char* pidfile)
|
||||
{
|
||||
m_status = false;
|
||||
m_pidfile = file;
|
||||
m_pidfile = pidfile;
|
||||
m_pidfd = 0;
|
||||
|
||||
pid_t pid;
|
||||
|
||||
+44
-10
@@ -17,32 +17,66 @@
|
||||
* along with ebusd. If not, see http://www.gnu.org/licenses/.
|
||||
*/
|
||||
|
||||
#ifndef LIBCORE_DAEMON_H_
|
||||
#define LIBCORE_DAEMON_H_
|
||||
#ifndef LIBUTILS_DAEMON_H_
|
||||
#define LIBUTILS_DAEMON_H_
|
||||
|
||||
/**
|
||||
* @brief class to daemonize a process.
|
||||
*/
|
||||
class Daemon
|
||||
{
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief create an instance and return the reference.
|
||||
* @return the reference to instance.
|
||||
*/
|
||||
static Daemon& Instance();
|
||||
~Daemon() {}
|
||||
|
||||
void run(const char* file);
|
||||
/**
|
||||
* @brief daemonize act process.
|
||||
* @param pidfile the name of the pid file.
|
||||
*/
|
||||
void run(const char* pidfile);
|
||||
|
||||
/**
|
||||
* @brief stop daemon and delete the pid file.
|
||||
*/
|
||||
void stop() { pidfile_close(); }
|
||||
|
||||
/**
|
||||
* @brief show actual status if daemonize.
|
||||
* @return true if process is a daemon.
|
||||
*/
|
||||
bool status() { return m_status; }
|
||||
|
||||
private:
|
||||
bool m_status;
|
||||
const char* m_pidfile;
|
||||
int m_pidfd;
|
||||
|
||||
/** private constructor - singleton pattern */
|
||||
Daemon() {}
|
||||
Daemon(const Daemon&);
|
||||
Daemon& operator= (const Daemon&);
|
||||
Daemon& operator=(const Daemon&);
|
||||
|
||||
/** status of process; true if we are a daemon */
|
||||
bool m_status;
|
||||
|
||||
/** name of the pid file*/
|
||||
const char* m_pidfile;
|
||||
|
||||
/** file descriptor of the pid file */
|
||||
int m_pidfd;
|
||||
|
||||
/**
|
||||
* @brief creates a pid file for process.
|
||||
* @return true if success.
|
||||
*/
|
||||
bool pidfile_open();
|
||||
|
||||
/**
|
||||
* @brief close and delete the pid file.
|
||||
* @return true if success.
|
||||
*/
|
||||
bool pidfile_close();
|
||||
|
||||
};
|
||||
|
||||
#endif // LIBCORE_DAEMON_H_
|
||||
#endif // LIBUTILS_DAEMON_H_
|
||||
|
||||
+26
-25
@@ -28,7 +28,10 @@
|
||||
#include <sys/time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
/** static char array with logging area names */
|
||||
static const char* AreaNames[Size_of_Areas] = { "bas", "net", "bus" };
|
||||
|
||||
/** static char array with logging level names */
|
||||
static const char* LevelNames[Size_of_Level] = { "error", "event", "trace", "debug" };
|
||||
|
||||
int calcAreas(const std::string areas)
|
||||
@@ -66,8 +69,8 @@ int calcLevel(const std::string level)
|
||||
}
|
||||
|
||||
|
||||
LogMessage::LogMessage(const int area, const int level, const std::string text, const Status status)
|
||||
: m_area(area), m_level(level), m_text(text), m_status(status)
|
||||
LogMessage::LogMessage(const int area, const int level, const std::string text, const bool running)
|
||||
: m_area(area), m_level(level), m_text(text), m_running(running)
|
||||
{
|
||||
char time[24];
|
||||
struct timeval tv;
|
||||
@@ -89,17 +92,17 @@ LogMessage::LogMessage(const int area, const int level, const std::string text,
|
||||
void LogSink::addMessage(const LogMessage& message)
|
||||
{
|
||||
LogMessage* tmp = new LogMessage(LogMessage(message));
|
||||
m_queue.add((tmp));
|
||||
m_logQueue.add((tmp));
|
||||
}
|
||||
|
||||
void* LogSink::run()
|
||||
{
|
||||
while (1) {
|
||||
LogMessage* message = m_queue.remove();
|
||||
if (message->getStatus() == LogMessage::End) {
|
||||
LogMessage* message = m_logQueue.remove();
|
||||
if (message->isRunning() == false) {
|
||||
delete message;
|
||||
while (m_queue.size() == true) {
|
||||
LogMessage* message = m_queue.remove();
|
||||
while (m_logQueue.size() == true) {
|
||||
LogMessage* message = m_logQueue.remove();
|
||||
write(*message);
|
||||
delete message;
|
||||
}
|
||||
@@ -114,8 +117,6 @@ void* LogSink::run()
|
||||
|
||||
|
||||
|
||||
int LogConsole::m_numInstance = 0;
|
||||
|
||||
void LogConsole::write(const LogMessage& message) const
|
||||
{
|
||||
std::cout << message.getTime() << " ["
|
||||
@@ -126,11 +127,9 @@ void LogConsole::write(const LogMessage& message) const
|
||||
|
||||
|
||||
|
||||
int LogFile::m_numInstance = 0;
|
||||
|
||||
void LogFile::write(const LogMessage& message) const
|
||||
{
|
||||
std::fstream file(m_filename.c_str(), std::ios::out | std::ios::app);
|
||||
std::fstream file(m_file.c_str(), std::ios::out | std::ios::app);
|
||||
|
||||
if (file.is_open() == true) {
|
||||
file << message.getTime() << " ["
|
||||
@@ -143,19 +142,19 @@ void LogFile::write(const LogMessage& message) const
|
||||
|
||||
|
||||
|
||||
LogInstance& LogInstance::Instance()
|
||||
Logger& Logger::Instance()
|
||||
{
|
||||
static LogInstance instance;
|
||||
static Logger instance;
|
||||
return (instance);
|
||||
}
|
||||
|
||||
LogInstance::~LogInstance()
|
||||
Logger::~Logger()
|
||||
{
|
||||
while (m_sinks.empty() == false)
|
||||
*this -= *(m_sinks.begin());
|
||||
}
|
||||
|
||||
LogInstance& LogInstance::operator+= (LogSink* sink)
|
||||
Logger& Logger::operator+=(LogSink* sink)
|
||||
{
|
||||
sinkCI_t itEnd = m_sinks.end();
|
||||
sinkCI_t it = std::find(m_sinks.begin(), itEnd, sink);
|
||||
@@ -166,7 +165,7 @@ LogInstance& LogInstance::operator+= (LogSink* sink)
|
||||
return (*this);
|
||||
}
|
||||
|
||||
LogInstance& LogInstance::operator-= (const LogSink* sink)
|
||||
Logger& Logger::operator-=(const LogSink* sink)
|
||||
{
|
||||
sinkCI_t itEnd = m_sinks.end();
|
||||
sinkCI_t it = std::find(m_sinks.begin(), itEnd, sink);
|
||||
@@ -181,7 +180,7 @@ LogInstance& LogInstance::operator-= (const LogSink* sink)
|
||||
return (*this);
|
||||
}
|
||||
|
||||
void LogInstance::log(const int area, const int level, const std::string& data, ...)
|
||||
void Logger::log(const int area, const int level, const std::string& data, ...)
|
||||
{
|
||||
if (m_running == true) {
|
||||
char* tmp;
|
||||
@@ -190,7 +189,7 @@ void LogInstance::log(const int area, const int level, const std::string& data,
|
||||
|
||||
if (vasprintf(&tmp, data.c_str(), ap) != -1) {
|
||||
std::string buffer(tmp);
|
||||
m_messages.add(new LogMessage(LogMessage(area, level, buffer, LogMessage::Run)));
|
||||
m_logQueue.add(new LogMessage(area, level, buffer));
|
||||
}
|
||||
|
||||
va_end(ap);
|
||||
@@ -199,12 +198,12 @@ void LogInstance::log(const int area, const int level, const std::string& data,
|
||||
|
||||
}
|
||||
|
||||
void* LogInstance::run()
|
||||
void* Logger::run()
|
||||
{
|
||||
m_running = true;
|
||||
|
||||
while (m_running == true) {
|
||||
LogMessage* message = m_messages.remove();
|
||||
LogMessage* message = m_logQueue.remove();
|
||||
|
||||
sinkCI_t iter = m_sinks.begin();
|
||||
|
||||
@@ -213,13 +212,15 @@ void* LogInstance::run()
|
||||
|
||||
if (((*iter)->getAreas() & message->getArea()
|
||||
&& (*iter)->getLevel() >= message->getLevel())
|
||||
&& message->getStatus() == LogMessage::Run) {
|
||||
&& message->isRunning() == true) {
|
||||
(*iter)->addMessage(*message);
|
||||
} else if (message->getStatus() == LogMessage::End) {
|
||||
}
|
||||
else if (message->isRunning() == false) {
|
||||
(*iter)->addMessage(*message);
|
||||
m_running = false;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -229,8 +230,8 @@ void* LogInstance::run()
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void LogInstance::stop()
|
||||
void Logger::stop()
|
||||
{
|
||||
m_messages.add(new LogMessage(LogMessage(bas, error, "", LogMessage::End)));
|
||||
m_logQueue.add(new LogMessage(LogMessage(bas, error, "", false)));
|
||||
usleep(100000);
|
||||
}
|
||||
|
||||
+201
-60
@@ -17,8 +17,8 @@
|
||||
* along with ebusd. If not, see http://www.gnu.org/licenses/.
|
||||
*/
|
||||
|
||||
#ifndef LIBCORE_LOGGER_H_
|
||||
#define LIBCORE_LOGGER_H_
|
||||
#ifndef LIBUTILS_LOGGER_H_
|
||||
#define LIBUTILS_LOGGER_H_
|
||||
|
||||
#include "wqueue.h"
|
||||
#include "thread.h"
|
||||
@@ -28,154 +28,295 @@
|
||||
#include <vector>
|
||||
#include <cstdarg>
|
||||
|
||||
enum Areas { bas=1, net=2, bus=4, all=7, Size_of_Areas=3 };
|
||||
enum Level { error=0, event, trace, debug, Size_of_Level };
|
||||
/** available types for all subsystems */
|
||||
enum AreasType {
|
||||
bas=1, // basis
|
||||
net=2, // network
|
||||
bus=4, // ebus
|
||||
all=7, // type for all subsystems
|
||||
Size_of_Areas=3, // number of possible areas
|
||||
};
|
||||
|
||||
/** available logging levels */
|
||||
enum LevelType {
|
||||
error=0, //
|
||||
event, //
|
||||
trace, //
|
||||
debug, //
|
||||
Size_of_Level, // number of possible levels
|
||||
};
|
||||
|
||||
/** global function to get calculate logging areas */
|
||||
int calcAreas(const std::string areas);
|
||||
|
||||
/** global function to get calculate logging level */
|
||||
int calcLevel(const std::string level);
|
||||
|
||||
|
||||
/**
|
||||
* @brief class which describes a logging message itself.
|
||||
*/
|
||||
class LogMessage
|
||||
{
|
||||
|
||||
public:
|
||||
enum Status { Run, End };
|
||||
|
||||
LogMessage(const int area, const int level, const std::string text, const Status status);
|
||||
|
||||
~LogMessage() {}
|
||||
|
||||
LogMessage(const LogMessage& src)
|
||||
: m_area(src.m_area), m_level(src.m_level), m_text(src.m_text),
|
||||
m_status(src.m_status), m_time(src.m_time) {}
|
||||
|
||||
void operator= (const LogMessage& src)
|
||||
{ m_area = src.m_area; m_level = src.m_level; m_text = src.m_text;
|
||||
m_status = src.m_status; m_time = src.m_time; }
|
||||
/**
|
||||
* @brief creates a new logging message.
|
||||
* @param area the logging area of the message.
|
||||
* @param level the logging level of the message.
|
||||
* @param text the logging message.
|
||||
* @param running the status of logging subsystem.
|
||||
*/
|
||||
LogMessage(const int area, const int level, const std::string text, const bool running=true);
|
||||
|
||||
/**
|
||||
* @brief get the logging area.
|
||||
* @return the logging area.
|
||||
*/
|
||||
int getArea() const { return (m_area); }
|
||||
|
||||
/**
|
||||
* @brief get the logging level.
|
||||
* @return the logging level.
|
||||
*/
|
||||
int getLevel() const { return(m_level); }
|
||||
|
||||
/**
|
||||
* @brief get the logging text.
|
||||
* @return the logging text.
|
||||
*/
|
||||
std::string getText() const { return (m_text.c_str()); }
|
||||
Status getStatus() const { return (m_status); }
|
||||
|
||||
/**
|
||||
* @brief status of logging subsystem.
|
||||
* @return false if logging subsystem is going down.
|
||||
*/
|
||||
bool isRunning() const { return m_running; }
|
||||
|
||||
/**
|
||||
* @brief get the logging timestamp.
|
||||
* @return the logging timestamp.
|
||||
*/
|
||||
std::string getTime() const { return (m_time.c_str()); }
|
||||
|
||||
private:
|
||||
/** the logging area */
|
||||
int m_area;
|
||||
|
||||
/** the logging level */
|
||||
int m_level;
|
||||
|
||||
/** the logging message */
|
||||
std::string m_text;
|
||||
Status m_status;
|
||||
|
||||
/** true if this instance is running */
|
||||
bool m_running;
|
||||
|
||||
/** the logging timestamp */
|
||||
std::string m_time;
|
||||
|
||||
};
|
||||
|
||||
enum Type { Console, Logfile };
|
||||
|
||||
/**
|
||||
* @brief base class for all type of logging sinks.
|
||||
*/
|
||||
class LogSink : public Thread
|
||||
{
|
||||
|
||||
public:
|
||||
LogSink(const int areas, const int level, const Type type, const char* name)
|
||||
: m_areas(areas), m_level(level), m_type(type), m_name(name) {}
|
||||
|
||||
virtual ~LogSink() {}
|
||||
/**
|
||||
* @brief creates a virtual logging sink.
|
||||
* @param areas the logging areas.
|
||||
* @param level the logging level.
|
||||
*/
|
||||
LogSink(const int areas, const int level) : m_areas(areas), m_level(level) {}
|
||||
|
||||
/**
|
||||
* @brief adds the logging message to internal message queue.
|
||||
* @param message a reference to logging message.
|
||||
*/
|
||||
void addMessage(const LogMessage& message);
|
||||
|
||||
/**
|
||||
* @brief endless loop for logging sink instance.
|
||||
* @return void pointer.
|
||||
*/
|
||||
void* run();
|
||||
|
||||
/**
|
||||
* @brief get the logging areas.
|
||||
* @return the logging areas.
|
||||
*/
|
||||
int getAreas() const { return (m_areas); }
|
||||
|
||||
/**
|
||||
* @brief set the logging areas.
|
||||
* @param areas the logging areas.
|
||||
*/
|
||||
void setAreas(const int& areas) { m_areas = areas; }
|
||||
|
||||
/**
|
||||
* @brief get the logging level.
|
||||
* @return the logging level.
|
||||
*/
|
||||
int getLevel() const { return (m_level); }
|
||||
|
||||
/**
|
||||
* @brief set the logging level.
|
||||
* @param level the logging level.
|
||||
*/
|
||||
void setLevel(const int& level) { m_level = level; }
|
||||
|
||||
Type getType() const { return (m_type); }
|
||||
const char* getName() const { return (m_name.c_str()); }
|
||||
|
||||
protected:
|
||||
WQueue<LogMessage*> m_queue;
|
||||
/** queue for logging messages */
|
||||
WQueue<LogMessage*> m_logQueue;
|
||||
|
||||
private:
|
||||
/** the logging areas */
|
||||
int m_areas;
|
||||
int m_level;
|
||||
Type m_type;
|
||||
std::string m_name;
|
||||
|
||||
/** the logging level */
|
||||
int m_level;
|
||||
|
||||
/**
|
||||
* @brief virtual function for writing the logging message.
|
||||
* @param message the logging message.
|
||||
*/
|
||||
virtual void write(const LogMessage& message) const = 0;
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief class for console logging sink type.
|
||||
*/
|
||||
class LogConsole : public LogSink
|
||||
{
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief creates a console logging sink.
|
||||
* @param areas the logging areas.
|
||||
* @param level the logging level.
|
||||
* @param name the thread name for logging sink.
|
||||
*/
|
||||
LogConsole(const int areas, const int level, const char* name)
|
||||
: LogSink(areas, level, Console, name), m_instance(++m_numInstance)
|
||||
{ this->start(name); }
|
||||
|
||||
~LogConsole() {}
|
||||
: LogSink(areas, level) { this->start(name); }
|
||||
|
||||
private:
|
||||
const int m_instance;
|
||||
static int m_numInstance;
|
||||
|
||||
/**
|
||||
* @brief write the logging message to stdout.
|
||||
* @param message the logging message.
|
||||
*/
|
||||
void write(const LogMessage& message) const;
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief class for logfile logging sink type.
|
||||
*/
|
||||
class LogFile : public LogSink
|
||||
{
|
||||
|
||||
public:
|
||||
LogFile(const int areas, const int level, const char* name, const char* filename)
|
||||
: LogSink(areas, level, Logfile, name), m_filename(filename), m_instance(++m_numInstance)
|
||||
{ this->start(name); }
|
||||
|
||||
~LogFile() {}
|
||||
/**
|
||||
* @brief creates a log file logging sink.
|
||||
* @param areas the logging areas.
|
||||
* @param level the logging level.
|
||||
* @param name the thread name for logging sink.
|
||||
* @param file the log file.
|
||||
*/
|
||||
LogFile(const int areas, const int level, const char* name, const char* file)
|
||||
: LogSink(areas, level), m_file(file) { this->start(name); }
|
||||
|
||||
private:
|
||||
std::string m_filename;
|
||||
const int m_instance;
|
||||
static int m_numInstance;
|
||||
/** the logging file */
|
||||
std::string m_file;
|
||||
|
||||
/**
|
||||
* @brief write the logging message to specific log file.
|
||||
* @param message the logging message.
|
||||
*/
|
||||
void write(const LogMessage& message) const;
|
||||
|
||||
};
|
||||
|
||||
class LogInstance : public Thread
|
||||
/**
|
||||
* @brief logger base class which provide the logging interface.
|
||||
*/
|
||||
class Logger : public Thread
|
||||
{
|
||||
|
||||
public:
|
||||
static LogInstance& Instance();
|
||||
/**
|
||||
* @brief create an instance and return the reference.
|
||||
* @return the reference to instance.
|
||||
*/
|
||||
static Logger& Instance();
|
||||
|
||||
~LogInstance();
|
||||
/**
|
||||
* @brief destructor.
|
||||
*/
|
||||
~Logger();
|
||||
|
||||
LogInstance& operator+= (LogSink* sink);
|
||||
LogInstance& operator-= (const LogSink* sink);
|
||||
/**
|
||||
* @brief adds a logging sink and returns the reference to logger.
|
||||
* @param pointer of logging sink.
|
||||
* @return the reference to logger.
|
||||
*/
|
||||
Logger& operator+=(LogSink* sink);
|
||||
|
||||
/**
|
||||
* @brief removes a logging sink and returns the reference to logger.
|
||||
* @param pointer of logging sink.
|
||||
* @return the reference to logger.
|
||||
*/
|
||||
Logger& operator-=(const LogSink* sink);
|
||||
|
||||
/**
|
||||
* @brief creates a logging message and add them to internal message queue.
|
||||
* @param area the logging area of the message.
|
||||
* @param level the logging level of the message.
|
||||
* @param text the logging message.
|
||||
* @param ... possible 'variable argument lists'.
|
||||
*/
|
||||
void log(const int area, const int level, const std::string& text, ...);
|
||||
|
||||
int getNumberOfSinks() const { return(m_sinks.size()); }
|
||||
LogSink* getSink(const int Index) const { return(m_sinks[Index]); }
|
||||
/**
|
||||
* @brief returns the sink at the specified index.
|
||||
* @param index the index of the sink to return.
|
||||
* @return the sink at the specified index.
|
||||
*/
|
||||
LogSink* getSink(const int index) const { return(m_sinks[index]); }
|
||||
|
||||
/**
|
||||
* @brief endless loop for logger instance.
|
||||
* @return void pointer.
|
||||
*/
|
||||
void* run();
|
||||
|
||||
/**
|
||||
* @brief shutdown logger subsystem.
|
||||
*/
|
||||
void stop();
|
||||
|
||||
private:
|
||||
LogInstance() {}
|
||||
LogInstance(const LogInstance&);
|
||||
LogInstance& operator= (const LogInstance&);
|
||||
/** private constructor - singleton pattern */
|
||||
Logger() {}
|
||||
Logger(const Logger&);
|
||||
Logger& operator=(const Logger&);
|
||||
|
||||
/** typedefs for a vector of type LogSink* */
|
||||
typedef std::vector<LogSink*> sink_t;
|
||||
typedef std::vector<LogSink*>::iterator sinkCI_t;
|
||||
|
||||
/** vector of available logging sinks */
|
||||
sink_t m_sinks;
|
||||
|
||||
WQueue<LogMessage*> m_messages;
|
||||
/** queue for logging messages */
|
||||
WQueue<LogMessage*> m_logQueue;
|
||||
|
||||
/** true if this instance is running */
|
||||
bool m_running;
|
||||
|
||||
};
|
||||
|
||||
#endif // LIBCORE_LOGGER_H_
|
||||
#endif // LIBUTILS_LOGGER_H_
|
||||
|
||||
@@ -17,37 +17,26 @@
|
||||
* along with ebusd. If not, see http://www.gnu.org/licenses/.
|
||||
*/
|
||||
|
||||
#include "dump.h"
|
||||
#include <fstream>
|
||||
#include <cstdio>
|
||||
#include "notify.h"
|
||||
|
||||
namespace libebus
|
||||
Notify::Notify()
|
||||
{
|
||||
int pipefd[2];
|
||||
int ret = pipe(pipefd);
|
||||
|
||||
int Dump::write(const char* byte)
|
||||
{
|
||||
int ret = 0;
|
||||
if (ret == 0) {
|
||||
m_recvfd = pipefd[0];
|
||||
m_sendfd = pipefd[1];
|
||||
|
||||
std::ofstream fs(m_filename.c_str(), std::ios::out | std::ios::binary | std::ios::app);
|
||||
|
||||
if (fs == 0)
|
||||
return -1;
|
||||
|
||||
fs.write(byte, 1);
|
||||
|
||||
if (fs.tellp() >= m_filesize * 1024) {
|
||||
std::string oldfile;
|
||||
oldfile += m_filename;
|
||||
oldfile += ".old";
|
||||
ret = rename(m_filename.c_str(), oldfile.c_str());
|
||||
fcntl(m_sendfd, F_SETFL, O_NONBLOCK);
|
||||
}
|
||||
|
||||
fs.close();
|
||||
}
|
||||
|
||||
return ret;
|
||||
Notify::~Notify()
|
||||
{
|
||||
close(m_sendfd);
|
||||
close(m_recvfd);
|
||||
}
|
||||
|
||||
|
||||
|
||||
} //namespace
|
||||
|
||||
+28
-18
@@ -17,40 +17,50 @@
|
||||
* along with ebusd. If not, see http://www.gnu.org/licenses/.
|
||||
*/
|
||||
|
||||
#ifndef LIBCORE_NOTIFY_H_
|
||||
#define LIBCORE_NOTIFY_H_
|
||||
#ifndef LIBUTILS_NOTIFY_H_
|
||||
#define LIBUTILS_NOTIFY_H_
|
||||
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
/**
|
||||
* @brief class to notify other thread per pipe.
|
||||
*/
|
||||
class Notify
|
||||
{
|
||||
|
||||
public:
|
||||
Notify()
|
||||
{
|
||||
int pipefd[2];
|
||||
int ret = pipe(pipefd);
|
||||
/**
|
||||
* @brief constructs a new instance and do notifying.
|
||||
*/
|
||||
Notify();
|
||||
|
||||
if (ret == 0) {
|
||||
m_recvfd = pipefd[0];
|
||||
m_sendfd = pipefd[1];
|
||||
/**
|
||||
* @brief destructor.
|
||||
*/
|
||||
~Notify();
|
||||
|
||||
fcntl(m_sendfd, F_SETFL, O_NONBLOCK);
|
||||
}
|
||||
/**
|
||||
* @brief file descriptor to watch for notify event.
|
||||
* @return the notification value.
|
||||
*/
|
||||
int notifyFD() { return m_recvfd; }
|
||||
|
||||
}
|
||||
virtual ~Notify() { close(m_sendfd); close(m_recvfd); }
|
||||
|
||||
int notifyFD() const { return m_recvfd; }
|
||||
/**
|
||||
* @brief write notify event to file descriptor.
|
||||
* @return result of writing notification.
|
||||
*/
|
||||
int notify() const { return write(m_sendfd,"1",1); }
|
||||
|
||||
private:
|
||||
int m_recvfd;
|
||||
int m_sendfd;
|
||||
/** file descriptor to watch */
|
||||
int m_recvfd;
|
||||
|
||||
/** file descriptor to notify */
|
||||
int m_sendfd;
|
||||
|
||||
};
|
||||
|
||||
#endif // LIBCORE_NOTIFY_H_
|
||||
#endif // LIBUTILS_NOTIFY_H_
|
||||
|
||||
|
||||
|
||||
@@ -19,11 +19,7 @@
|
||||
|
||||
#include "tcpsocket.h"
|
||||
#include <cstdlib>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
#include <string.h>
|
||||
|
||||
@@ -17,72 +17,155 @@
|
||||
* along with ebusd. If not, see http://www.gnu.org/licenses/.
|
||||
*/
|
||||
|
||||
#ifndef LIBCORE_TCPSOCKET_H_
|
||||
#define LIBCORE_TCPSOCKET_H_
|
||||
#ifndef LIBUTILS_TCPSOCKET_H_
|
||||
#define LIBUTILS_TCPSOCKET_H_
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <unistd.h>
|
||||
#include <string>
|
||||
|
||||
/**
|
||||
* @brief class for low level tcp socket operations. (open, close, send, receive).
|
||||
*/
|
||||
class TCPSocket
|
||||
{
|
||||
|
||||
public:
|
||||
/** grant access for friend classes */
|
||||
friend class TCPClient;
|
||||
friend class TCPServer;
|
||||
|
||||
/**
|
||||
* @brief destructor.
|
||||
*/
|
||||
~TCPSocket() { close(m_sfd); }
|
||||
|
||||
ssize_t recv(char* buffer, size_t len) { return read(m_sfd, buffer, len); }
|
||||
/**
|
||||
* @brief write bytes to opened file descriptor.
|
||||
* @param buffer data to send.
|
||||
* @param len number of bytes to send.
|
||||
* @return number of written bytes or -1 if an error has occured.
|
||||
*/
|
||||
ssize_t send(const char* buffer, size_t len) { return write(m_sfd, buffer, len); }
|
||||
|
||||
/**
|
||||
* @brief read bytes from opened file descriptor.
|
||||
* @param buffer for received bytes.
|
||||
* @param len size of the receive buffer.
|
||||
* @return number of read bytes or -1 if an error has occured.
|
||||
*/
|
||||
ssize_t recv(char* buffer, size_t len) { return read(m_sfd, buffer, len); }
|
||||
|
||||
/**
|
||||
* @brief returns the tcp port.
|
||||
* @return the tcp port.
|
||||
*/
|
||||
int getPort() const { return m_port; }
|
||||
|
||||
/**
|
||||
* @brief returns the ip address.
|
||||
* @return the ip address.
|
||||
*/
|
||||
std::string getIP() const { return m_ip; }
|
||||
|
||||
/**
|
||||
* @brief returns the file descriptor.
|
||||
* @return the file descriptor.
|
||||
*/
|
||||
int getFD() const { return m_sfd; }
|
||||
|
||||
/**
|
||||
* @brief returns status of file descriptor.
|
||||
* @return true if file descriptor is valid.
|
||||
*/
|
||||
bool isValid();
|
||||
|
||||
private:
|
||||
/** file descriptor from tcp socket */
|
||||
int m_sfd;
|
||||
|
||||
/** port of tcp socket */
|
||||
int m_port;
|
||||
|
||||
/** ip address of tcp socket */
|
||||
std::string m_ip;
|
||||
|
||||
/**
|
||||
* @brief private constructor, limited access only for friend classes.
|
||||
* @param sfd the file desctriptor of tcp socket.
|
||||
* @param address struct which holds the ip address.
|
||||
*/
|
||||
TCPSocket(int sfd, struct sockaddr_in* address);
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief class to initiate a tcp socket connection to a listening server.
|
||||
*/
|
||||
class TCPClient
|
||||
{
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief initiate a tcp socket connection to a listening server.
|
||||
* @param server the server name or ip address to connect.
|
||||
* @param port the tcp port.
|
||||
* @return pointer to an opened tcp socket.
|
||||
*/
|
||||
TCPSocket* connect(const std::string& server, const int& port);
|
||||
|
||||
private:
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief class for a tcp based network server.
|
||||
*/
|
||||
class TCPServer
|
||||
{
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief creates a new instance of a listening tcp server.
|
||||
* @param port the tcp port.
|
||||
* @param address the ip address.
|
||||
*/
|
||||
TCPServer(const int port, const std::string address)
|
||||
: m_lfd(0), m_port(port), m_address(address), m_listening(false) {}
|
||||
|
||||
/**
|
||||
* @brief destructor.
|
||||
*/
|
||||
~TCPServer() { if (m_lfd > 0) {close(m_lfd);} }
|
||||
|
||||
/**
|
||||
* @brief start listening of tcp socket.
|
||||
*/
|
||||
int start();
|
||||
|
||||
/**
|
||||
* @brief accept an incomming tcp connection and create a local tcp socket for communication.
|
||||
* @return pointer to an opened tcp socket.
|
||||
*/
|
||||
TCPSocket* newSocket();
|
||||
|
||||
/**
|
||||
* @brief returns the file descriptor.
|
||||
* @return the file descriptor.
|
||||
*/
|
||||
int getFD() const { return m_lfd; }
|
||||
|
||||
private:
|
||||
/** file descriptor from listening tcp socket */
|
||||
int m_lfd;
|
||||
|
||||
/** listening tcp port */
|
||||
int m_port;
|
||||
|
||||
/** listening tcp socket ip address */
|
||||
std::string m_address;
|
||||
|
||||
/** true if object is already listening */
|
||||
bool m_listening;
|
||||
|
||||
};
|
||||
|
||||
#endif // LIBCORE_TCPSOCKET_H_
|
||||
#endif // LIBUTILS_TCPSOCKET_H_
|
||||
|
||||
|
||||
@@ -17,11 +17,19 @@
|
||||
* along with ebusd. If not, see http://www.gnu.org/licenses/.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include "thread.h"
|
||||
|
||||
/**
|
||||
* @brief static function which will be called on thread startup.
|
||||
* @return void pointer.
|
||||
*/
|
||||
static void* runThread(void* arg)
|
||||
{
|
||||
return ((Thread *)arg)->run();
|
||||
return ((Thread*)arg)->run();
|
||||
}
|
||||
|
||||
Thread::~Thread()
|
||||
@@ -39,7 +47,11 @@ int Thread::start(const char* name)
|
||||
int result = pthread_create(&m_threadid, NULL, runThread, this);
|
||||
|
||||
if (result == 0) {
|
||||
|
||||
#ifdef HAVE_PTHREAD_SETNAME_NP
|
||||
pthread_setname_np(m_threadid, name);
|
||||
#endif
|
||||
|
||||
m_running = true;
|
||||
}
|
||||
|
||||
|
||||
+42
-3
@@ -17,30 +17,69 @@
|
||||
* along with ebusd. If not, see http://www.gnu.org/licenses/.
|
||||
*/
|
||||
|
||||
#ifndef LIBCORE_THREAD_H_
|
||||
#define LIBCORE_THREAD_H_
|
||||
#ifndef LIBUTILS_THREAD_H_
|
||||
#define LIBUTILS_THREAD_H_
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
/**
|
||||
* @brief wrapper class for pthread.
|
||||
*/
|
||||
class Thread
|
||||
{
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief constructor.
|
||||
*/
|
||||
Thread() : m_threadid(0), m_running(false), m_detached(false) {}
|
||||
|
||||
/**
|
||||
* @brief virtual destructor.
|
||||
*/
|
||||
virtual ~Thread();
|
||||
|
||||
/**
|
||||
* @brief create the thread and set name for process list.
|
||||
* @param name the thread name which show in process list.
|
||||
* @return value of thread creating.
|
||||
*/
|
||||
int start(const char* name);
|
||||
|
||||
/**
|
||||
* @brief join the thread.
|
||||
* @return value of thread joining.
|
||||
*/
|
||||
int join();
|
||||
|
||||
/**
|
||||
* @brief detach the thread.
|
||||
* @return value of thread detaching.
|
||||
*/
|
||||
int detach();
|
||||
|
||||
/**
|
||||
* @brief return the thread id.
|
||||
* @return own thread id.
|
||||
*/
|
||||
pthread_t self() {return m_threadid; }
|
||||
|
||||
/**
|
||||
* @brief virtul function which must be implemented in derived class.
|
||||
* @return void pointer.
|
||||
*/
|
||||
virtual void* run() = 0;
|
||||
|
||||
private:
|
||||
/** own thread id */
|
||||
pthread_t m_threadid;
|
||||
|
||||
/** true if thread is running */
|
||||
bool m_running;
|
||||
|
||||
/** true if thread is detached */
|
||||
bool m_detached;
|
||||
|
||||
};
|
||||
|
||||
#endif // LIBCORE_THREAD_H_
|
||||
#endif // LIBUTILS_THREAD_H_
|
||||
|
||||
+35
-4
@@ -17,28 +17,42 @@
|
||||
* along with ebusd. If not, see http://www.gnu.org/licenses/.
|
||||
*/
|
||||
|
||||
#ifndef LIBCORE_WQUEUE_H_
|
||||
#define LIBCORE_WQUEUE_H_
|
||||
#ifndef LIBUTILS_WQUEUE_H_
|
||||
#define LIBUTILS_WQUEUE_H_
|
||||
|
||||
#include <list>
|
||||
#include <pthread.h>
|
||||
|
||||
template <typename T> class WQueue
|
||||
/**
|
||||
* @brief queue class template for all kinds data types with exclusiv lock.
|
||||
*/
|
||||
template <typename T>
|
||||
class WQueue
|
||||
{
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief constructs a new instance.
|
||||
*/
|
||||
WQueue()
|
||||
{
|
||||
pthread_mutex_init(&m_mutex, NULL);
|
||||
pthread_cond_init(&m_cond, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief destructor.
|
||||
*/
|
||||
~WQueue()
|
||||
{
|
||||
pthread_mutex_destroy(&m_mutex);
|
||||
pthread_cond_destroy(&m_cond);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief add a new item to the end of queue.
|
||||
* @param item to add.
|
||||
*/
|
||||
void add(T item)
|
||||
{
|
||||
pthread_mutex_lock(&m_mutex);
|
||||
@@ -49,6 +63,10 @@ public:
|
||||
pthread_mutex_unlock(&m_mutex);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief remove the first item from queue.
|
||||
* @return the item.
|
||||
*/
|
||||
T remove()
|
||||
{
|
||||
pthread_mutex_lock(&m_mutex);
|
||||
@@ -64,6 +82,10 @@ public:
|
||||
return item;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief return the first item from queue without remove.
|
||||
* @return the item.
|
||||
*/
|
||||
T next()
|
||||
{
|
||||
pthread_mutex_lock(&m_mutex);
|
||||
@@ -78,6 +100,10 @@ public:
|
||||
return item;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief the number of entries inside queue.
|
||||
* @return the size.
|
||||
*/
|
||||
int size()
|
||||
{
|
||||
pthread_mutex_lock(&m_mutex);
|
||||
@@ -90,10 +116,15 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
/** the queue itself */
|
||||
std::list<T> m_queue;
|
||||
|
||||
/** mutex variable for exclusive lock */
|
||||
pthread_mutex_t m_mutex;
|
||||
|
||||
/** condition variable for exclusive lock */
|
||||
pthread_cond_t m_cond;
|
||||
|
||||
};
|
||||
|
||||
#endif // LIBCORE_WQUEUE_H_
|
||||
#endif // LIBUTILS_WQUEUE_H_
|
||||
|
||||
Reference in New Issue
Block a user