diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..90cfebd --- /dev/null +++ b/.clang-format @@ -0,0 +1 @@ +BasedOnStyle : Google diff --git a/.gitignore b/.gitignore index 9fa9215..67029fd 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,5 @@ build/** operator.log .gitmodules -**/patch.txt \ No newline at end of file +**/patch.txt +.cache diff --git a/compile_commands.json b/compile_commands.json new file mode 100644 index 0000000..0b84865 --- /dev/null +++ b/compile_commands.json @@ -0,0 +1,332 @@ +[ + { + "arguments": [ + "/usr/lib64/ccache/g++", + "-g", + "-Wall", + "-Wextra", + "-Wno-deprecated-declarations", + "-D", + "_DEFAULT_SOURCE", + "-I./src/common", + "-I./src/ER_V", + "-Isrc/Ichor/driver/src", + "-Isrc/Ichor", + "-c", + "-o", + "/home/rtyocum/Documents/code/rit/capstone/operator/build/obj/common/conf/config.o", + "src/common/conf/config.cpp" + ], + "directory": "/home/rtyocum/Documents/code/rit/capstone/operator", + "file": "/home/rtyocum/Documents/code/rit/capstone/operator/src/common/conf/config.cpp", + "output": "/home/rtyocum/Documents/code/rit/capstone/operator/build/obj/common/conf/config.o" + }, + { + "arguments": [ + "/usr/lib64/ccache/g++", + "-g", + "-Wall", + "-Wextra", + "-Wno-deprecated-declarations", + "-D", + "_DEFAULT_SOURCE", + "-I./src/common", + "-I./src/ER_V", + "-Isrc/Ichor/driver/src", + "-Isrc/Ichor", + "-c", + "-o", + "/home/rtyocum/Documents/code/rit/capstone/operator/build/obj/common/arm/arm.o", + "src/common/arm/arm.cpp" + ], + "directory": "/home/rtyocum/Documents/code/rit/capstone/operator", + "file": "/home/rtyocum/Documents/code/rit/capstone/operator/src/common/arm/arm.cpp", + "output": "/home/rtyocum/Documents/code/rit/capstone/operator/build/obj/common/arm/arm.o" + }, + { + "arguments": [ + "/usr/lib64/ccache/g++", + "-g", + "-Wall", + "-Wextra", + "-Wno-deprecated-declarations", + "-D", + "_DEFAULT_SOURCE", + "-I./src/common", + "-I./src/ER_V", + "-Isrc/Ichor/driver/src", + "-Isrc/Ichor", + "-c", + "-o", + "/home/rtyocum/Documents/code/rit/capstone/operator/build/obj/common/util/timestamp.o", + "src/common/util/timestamp.c" + ], + "directory": "/home/rtyocum/Documents/code/rit/capstone/operator", + "file": "/home/rtyocum/Documents/code/rit/capstone/operator/src/common/util/timestamp.c", + "output": "/home/rtyocum/Documents/code/rit/capstone/operator/build/obj/common/util/timestamp.o" + }, + { + "arguments": [ + "/usr/lib64/ccache/g++", + "-g", + "-Wall", + "-Wextra", + "-Wno-deprecated-declarations", + "-D", + "_DEFAULT_SOURCE", + "-I./src/common", + "-I./src/ER_V", + "-Isrc/Ichor/driver/src", + "-Isrc/Ichor", + "-c", + "-o", + "/home/rtyocum/Documents/code/rit/capstone/operator/build/obj/common/data/s_list.o", + "src/common/data/s_list.c" + ], + "directory": "/home/rtyocum/Documents/code/rit/capstone/operator", + "file": "/home/rtyocum/Documents/code/rit/capstone/operator/src/common/data/s_list.c", + "output": "/home/rtyocum/Documents/code/rit/capstone/operator/build/obj/common/data/s_list.o" + }, + { + "arguments": [ + "/usr/lib64/ccache/g++", + "-g", + "-Wall", + "-Wextra", + "-Wno-deprecated-declarations", + "-D", + "_DEFAULT_SOURCE", + "-I./src/common", + "-I./src/ER_V", + "-Isrc/Ichor/driver/src", + "-Isrc/Ichor", + "-c", + "-o", + "/home/rtyocum/Documents/code/rit/capstone/operator/build/obj/common/log/log.o", + "src/common/log/log.c" + ], + "directory": "/home/rtyocum/Documents/code/rit/capstone/operator", + "file": "/home/rtyocum/Documents/code/rit/capstone/operator/src/common/log/log.c", + "output": "/home/rtyocum/Documents/code/rit/capstone/operator/build/obj/common/log/log.o" + }, + { + "arguments": [ + "/usr/lib64/ccache/g++", + "-g", + "-Wall", + "-Wextra", + "-Wno-deprecated-declarations", + "-D", + "_DEFAULT_SOURCE", + "-I./src/common", + "-I./src/ER_V", + "-Isrc/Ichor/driver/src", + "-Isrc/Ichor", + "-c", + "-o", + "/home/rtyocum/Documents/code/rit/capstone/operator/build/obj/common/api/api.o", + "src/common/api/api.c" + ], + "directory": "/home/rtyocum/Documents/code/rit/capstone/operator", + "file": "/home/rtyocum/Documents/code/rit/capstone/operator/src/common/api/api.c", + "output": "/home/rtyocum/Documents/code/rit/capstone/operator/build/obj/common/api/api.o" + }, + { + "arguments": [ + "/usr/lib64/ccache/g++", + "-g", + "-Wall", + "-Wextra", + "-Wno-deprecated-declarations", + "-D", + "_DEFAULT_SOURCE", + "-I./src/common", + "-I./src/ER_V", + "-Isrc/Ichor/driver/src", + "-Isrc/Ichor", + "-c", + "-o", + "/home/rtyocum/Documents/code/rit/capstone/operator/build/obj/common/socket/socket.o", + "src/common/socket/socket.cpp" + ], + "directory": "/home/rtyocum/Documents/code/rit/capstone/operator", + "file": "/home/rtyocum/Documents/code/rit/capstone/operator/src/common/socket/socket.cpp", + "output": "/home/rtyocum/Documents/code/rit/capstone/operator/build/obj/common/socket/socket.o" + }, + { + "arguments": [ + "/usr/lib64/ccache/g++", + "-g", + "-Wall", + "-Wextra", + "-Wno-deprecated-declarations", + "-D", + "_DEFAULT_SOURCE", + "-I./src/common", + "-I./src/ER_V", + "-Isrc/Ichor/driver/src", + "-Isrc/Ichor", + "-c", + "-o", + "/home/rtyocum/Documents/code/rit/capstone/operator/build/obj/common/sub/sub.o", + "src/common/sub/sub.cpp" + ], + "directory": "/home/rtyocum/Documents/code/rit/capstone/operator", + "file": "/home/rtyocum/Documents/code/rit/capstone/operator/src/common/sub/sub.cpp", + "output": "/home/rtyocum/Documents/code/rit/capstone/operator/build/obj/common/sub/sub.o" + }, + { + "arguments": [ + "/usr/lib64/ccache/g++", + "-g", + "-Wall", + "-Wextra", + "-Wno-deprecated-declarations", + "-D", + "_DEFAULT_SOURCE", + "-I./src/common", + "-I./src/ER_V", + "-Isrc/Ichor/driver/src", + "-Isrc/Ichor", + "-c", + "-o", + "/home/rtyocum/Documents/code/rit/capstone/operator/build/obj/common/log/log_config.o", + "src/common/log/log_config.cpp" + ], + "directory": "/home/rtyocum/Documents/code/rit/capstone/operator", + "file": "/home/rtyocum/Documents/code/rit/capstone/operator/src/common/log/log_config.cpp", + "output": "/home/rtyocum/Documents/code/rit/capstone/operator/build/obj/common/log/log_config.o" + }, + { + "arguments": [ + "/usr/lib64/ccache/g++", + "-g", + "-Wall", + "-Wextra", + "-Wno-deprecated-declarations", + "-D", + "_DEFAULT_SOURCE", + "-I./src/common", + "-I./src/ER_V", + "-Isrc/Ichor/driver/src", + "-Isrc/Ichor", + "-c", + "-o", + "/home/rtyocum/Documents/code/rit/capstone/operator/build/obj/common/socket/socket_conf.o", + "src/common/socket/socket_conf.cpp" + ], + "directory": "/home/rtyocum/Documents/code/rit/capstone/operator", + "file": "/home/rtyocum/Documents/code/rit/capstone/operator/src/common/socket/socket_conf.cpp", + "output": "/home/rtyocum/Documents/code/rit/capstone/operator/build/obj/common/socket/socket_conf.o" + }, + { + "arguments": [ + "/usr/lib64/ccache/g++", + "-g", + "-Wall", + "-Wextra", + "-Wno-deprecated-declarations", + "-D", + "_DEFAULT_SOURCE", + "-I./src/common", + "-I./src/ER_V", + "-Isrc/Ichor/driver/src", + "-Isrc/Ichor", + "-c", + "-o", + "/home/rtyocum/Documents/code/rit/capstone/operator/build/obj/ER_V/erv_arm/erv.o", + "src/ER_V/erv_arm/erv.cpp" + ], + "directory": "/home/rtyocum/Documents/code/rit/capstone/operator", + "file": "/home/rtyocum/Documents/code/rit/capstone/operator/src/ER_V/erv_arm/erv.cpp", + "output": "/home/rtyocum/Documents/code/rit/capstone/operator/build/obj/ER_V/erv_arm/erv.o" + }, + { + "arguments": [ + "/usr/lib64/ccache/g++", + "-g", + "-Wall", + "-Wextra", + "-Wno-deprecated-declarations", + "-D", + "_DEFAULT_SOURCE", + "-I./src/common", + "-I./src/ER_V", + "-Isrc/Ichor/driver/src", + "-Isrc/Ichor", + "-c", + "-o", + "/home/rtyocum/Documents/code/rit/capstone/operator/build/obj/common/tmp/tmp.o", + "src/common/tmp/tmp.cpp" + ], + "directory": "/home/rtyocum/Documents/code/rit/capstone/operator", + "file": "/home/rtyocum/Documents/code/rit/capstone/operator/src/common/tmp/tmp.cpp", + "output": "/home/rtyocum/Documents/code/rit/capstone/operator/build/obj/common/tmp/tmp.o" + }, + { + "arguments": [ + "/usr/lib64/ccache/g++", + "-g", + "-Wall", + "-Wextra", + "-Wno-deprecated-declarations", + "-D", + "_DEFAULT_SOURCE", + "-I./src/common", + "-I./src/ER_V", + "-Isrc/Ichor/driver/src", + "-Isrc/Ichor", + "-c", + "-o", + "/home/rtyocum/Documents/code/rit/capstone/operator/build/obj/ER_V/erv_conf/erv_conf.o", + "src/ER_V/erv_conf/erv_conf.cpp" + ], + "directory": "/home/rtyocum/Documents/code/rit/capstone/operator", + "file": "/home/rtyocum/Documents/code/rit/capstone/operator/src/ER_V/erv_conf/erv_conf.cpp", + "output": "/home/rtyocum/Documents/code/rit/capstone/operator/build/obj/ER_V/erv_conf/erv_conf.o" + }, + { + "arguments": [ + "/usr/lib64/ccache/g++", + "-g", + "-Wall", + "-Wextra", + "-Wno-deprecated-declarations", + "-D", + "_DEFAULT_SOURCE", + "-I./src/common", + "-I./src/ER_V", + "-Isrc/Ichor/driver/src", + "-Isrc/Ichor", + "-c", + "-o", + "/home/rtyocum/Documents/code/rit/capstone/operator/build/obj/ER_V/acl/acl.o", + "src/ER_V/acl/acl.c" + ], + "directory": "/home/rtyocum/Documents/code/rit/capstone/operator", + "file": "/home/rtyocum/Documents/code/rit/capstone/operator/src/ER_V/acl/acl.c", + "output": "/home/rtyocum/Documents/code/rit/capstone/operator/build/obj/ER_V/acl/acl.o" + }, + { + "arguments": [ + "/usr/lib64/ccache/g++", + "-g", + "-Wall", + "-Wextra", + "-Wno-deprecated-declarations", + "-D", + "_DEFAULT_SOURCE", + "-I./src/common", + "-I./src/ER_V", + "-Isrc/Ichor/driver/src", + "-Isrc/Ichor", + "-c", + "-o", + "/home/rtyocum/Documents/code/rit/capstone/operator/build/obj/ER_V/main.o", + "src/ER_V/main.cpp" + ], + "directory": "/home/rtyocum/Documents/code/rit/capstone/operator", + "file": "/home/rtyocum/Documents/code/rit/capstone/operator/src/ER_V/main.cpp", + "output": "/home/rtyocum/Documents/code/rit/capstone/operator/build/obj/ER_V/main.o" + } +] diff --git a/src/ActiveMQ_Demo/consumer.cpp b/src/ActiveMQ_Demo/consumer.cpp index 0eb8600..e321706 100644 --- a/src/ActiveMQ_Demo/consumer.cpp +++ b/src/ActiveMQ_Demo/consumer.cpp @@ -15,25 +15,26 @@ * limitations under the License. */ -#include -#include -#include -#include #include -#include +#include #include -#include +#include #include -#include -#include -#include -#include #include -#include +#include #include +#include #include -#include +#include +#include +#include +#include +#include +#include +#include #include +#include + #include using namespace activemq; @@ -47,220 +48,205 @@ using namespace std; //////////////////////////////////////////////////////////////////////////////// class TAMQ_Consumer : public ExceptionListener, - public MessageListener, - public DefaultTransportListener { -private: - - Connection* connection; - Session* session; - Destination* destination; - MessageConsumer* consumer; - bool useTopic; - std::string brokerURI; - std::string destURI; - bool clientAck; - - char buff[512]; - -private: - - TAMQ_Consumer( const TAMQ_Consumer& ); - TAMQ_Consumer& operator= ( const TAMQ_Consumer& ); - -public: - - TAMQ_Consumer( const std::string& brokerURI, - const std::string& destURI, - bool useTopic = false, - bool clientAck = false ) : - connection(NULL), + public MessageListener, + public DefaultTransportListener { + private: + Connection *connection; + Session *session; + Destination *destination; + MessageConsumer *consumer; + bool useTopic; + std::string brokerURI; + std::string destURI; + bool clientAck; + + char buff[512]; + + private: + TAMQ_Consumer(const TAMQ_Consumer &); + TAMQ_Consumer &operator=(const TAMQ_Consumer &); + + public: + TAMQ_Consumer(const std::string &brokerURI, const std::string &destURI, + bool useTopic = false, bool clientAck = false) + : connection(NULL), session(NULL), destination(NULL), consumer(NULL), useTopic(useTopic), brokerURI(brokerURI), destURI(destURI), - clientAck(clientAck) { - } + clientAck(clientAck) {} - virtual ~TAMQ_Consumer() { - this->cleanup(); - } - - void close() { - this->cleanup(); - } + virtual ~TAMQ_Consumer() { this->cleanup(); } - void runConsumer() { + void close() { this->cleanup(); } - try { + void runConsumer() { + try { + // Create a ConnectionFactory + ActiveMQConnectionFactory *connectionFactory = + new ActiveMQConnectionFactory(brokerURI); - // Create a ConnectionFactory - ActiveMQConnectionFactory* connectionFactory = - new ActiveMQConnectionFactory( brokerURI ); + // Create a Connection + connection = connectionFactory->createConnection(); + delete connectionFactory; - // Create a Connection - connection = connectionFactory->createConnection(); - delete connectionFactory; + ActiveMQConnection *amqConnection = + dynamic_cast(connection); + if (amqConnection != NULL) { + amqConnection->addTransportListener(this); + } - ActiveMQConnection* amqConnection = dynamic_cast( connection ); - if( amqConnection != NULL ) { - amqConnection->addTransportListener( this ); - } + connection->start(); - connection->start(); + connection->setExceptionListener(this); - connection->setExceptionListener(this); + // Create a Session + if (clientAck) { + session = connection->createSession(Session::CLIENT_ACKNOWLEDGE); + } else { + session = connection->createSession(Session::AUTO_ACKNOWLEDGE); + } - // Create a Session - if( clientAck ) { - session = connection->createSession( Session::CLIENT_ACKNOWLEDGE ); - } else { - session = connection->createSession( Session::AUTO_ACKNOWLEDGE ); - } + // Create the destination (Topic or Queue) + if (useTopic) { + destination = session->createTopic(destURI); + } else { + destination = session->createQueue(destURI); + } - // Create the destination (Topic or Queue) - if( useTopic ) { - destination = session->createTopic( destURI ); - } else { - destination = session->createQueue( destURI ); - } + // Create a MessageConsumer from the Session to the Topic or Queue + consumer = session->createConsumer(destination); + consumer->setMessageListener(this); - // Create a MessageConsumer from the Session to the Topic or Queue - consumer = session->createConsumer( destination ); - consumer->setMessageListener( this ); - - } catch (CMSException& e) { - e.printStackTrace(); - } - } - - // Called from the consumer since this class is a registered MessageListener. - virtual void onMessage( const Message* message ) { - - static int count = 0; - - try - { - count++; - const BytesMessage* textMessage = - dynamic_cast< const BytesMessage* >( message ); - unsigned char* bytes = {0}; - - if( textMessage != NULL ) { - bytes = textMessage->getBodyBytes(); - } else { - bytes = {0}; - } - - if( clientAck ) { - message->acknowledge(); - } - - int iter = 0; - printf("Length: %d\n", textMessage->getBodyLength()); - for (int i = 0; i < textMessage->getBodyLength(); i++) - { - printf("i: %d\n", i); - iter += sprintf(&buff[iter], "0x%02X, ", bytes[i]); - } - - printf( "Message #%d Received: %s\n", count, buff ); - } catch (CMSException& e) { - e.printStackTrace(); - } + } catch (CMSException &e) { + e.printStackTrace(); } - - // If something bad happens you see it here as this class is also been - // registered as an ExceptionListener with the connection. - virtual void onException( const CMSException& ex AMQCPP_UNUSED ) { - printf("CMS Exception occurred. Shutting down client.\n"); - exit(1); + } + + // Called from the consumer since this class is a registered MessageListener. + virtual void onMessage(const Message *message) { + static int count = 0; + + try { + count++; + const BytesMessage *textMessage = + dynamic_cast(message); + unsigned char *bytes = {0}; + + if (textMessage != NULL) { + bytes = textMessage->getBodyBytes(); + } else { + bytes = {0}; + } + + if (clientAck) { + message->acknowledge(); + } + + int iter = 0; + printf("Length: %d\n", textMessage->getBodyLength()); + for (int i = 0; i < textMessage->getBodyLength(); i++) { + printf("i: %d\n", i); + iter += sprintf(&buff[iter], "0x%02X, ", bytes[i]); + } + + printf("Message #%d Received: %s\n", count, buff); + } catch (CMSException &e) { + e.printStackTrace(); } - - virtual void transportInterrupted() { - std::cout << "The Connection's Transport has been Interrupted." << std::endl; + } + + // If something bad happens you see it here as this class is also been + // registered as an ExceptionListener with the connection. + virtual void onException(const CMSException &ex AMQCPP_UNUSED) { + printf("CMS Exception occurred. Shutting down client.\n"); + exit(1); + } + + virtual void transportInterrupted() { + std::cout << "The Connection's Transport has been Interrupted." + << std::endl; + } + + virtual void transportResumed() { + std::cout << "The Connection's Transport has been Restored." << std::endl; + } + + private: + void cleanup() { + try { + if (connection != NULL) { + connection->close(); + } + } catch (CMSException &e) { + e.printStackTrace(); } - virtual void transportResumed() { - std::cout << "The Connection's Transport has been Restored." << std::endl; - } - -private: - - void cleanup(){ - - try { - if( connection != NULL ) { - connection->close(); - } - } catch ( CMSException& e ) { - e.printStackTrace(); - } - - delete destination; - delete consumer; - delete session; - delete connection; - } + delete destination; + delete consumer; + delete session; + delete connection; + } }; //////////////////////////////////////////////////////////////////////////////// -int main(int argc AMQCPP_UNUSED, char* argv[] AMQCPP_UNUSED) { - - activemq::library::ActiveMQCPP::initializeLibrary(); - - std::cout << "=====================================================\n"; - std::cout << "Starting the example:" << std::endl; - std::cout << "-----------------------------------------------------\n"; - - // Set the URI to point to the IPAddress of your broker. - // add any optional params to the url to enable things like - // tightMarshalling or tcp logging etc. See the CMS web site for - // a full list of configuration options. - // - // http://activemq.apache.org/cms/ - // - std::string brokerURI = - // "failover:(tcp://192.168.120.115:61616)"; - "failover:(tcp://127.0.0.1:61616)"; - - //============================================================ - // This is the Destination Name and URI options. Use this to - // customize where the consumer listens, to have the consumer - // use a topic or queue set the 'useTopics' flag. - //============================================================ - std::string destURI = "TEST.FOO"; //?consumer.prefetchSize=1"; - - //============================================================ - // set to true to use topics instead of queues - // Note in the code above that this causes createTopic or - // createQueue to be used in the consumer. - //============================================================ - bool useTopics = false; - - //============================================================ - // set to true if you want the consumer to use client ack mode - // instead of the default auto ack mode. - //============================================================ - bool clientAck = false; - - // Create the consumer - TAMQ_Consumer consumer( brokerURI, destURI, useTopics, clientAck ); - - // Start it up and it will listen forever. - consumer.runConsumer(); - - // Wait to exit. - std::cout << "Press 'q' to quit" << std::endl; - while( std::cin.get() != 'q') {} - - // All CMS resources should be closed before the library is shutdown. - consumer.close(); - - std::cout << "-----------------------------------------------------\n"; - std::cout << "Finished with the example." << std::endl; - std::cout << "=====================================================\n"; - - activemq::library::ActiveMQCPP::shutdownLibrary(); +int main(int argc AMQCPP_UNUSED, char *argv[] AMQCPP_UNUSED) { + activemq::library::ActiveMQCPP::initializeLibrary(); + + std::cout << "=====================================================\n"; + std::cout << "Starting the example:" << std::endl; + std::cout << "-----------------------------------------------------\n"; + + // Set the URI to point to the IPAddress of your broker. + // add any optional params to the url to enable things like + // tightMarshalling or tcp logging etc. See the CMS web site for + // a full list of configuration options. + // + // http://activemq.apache.org/cms/ + // + std::string brokerURI = + // "failover:(tcp://192.168.120.115:61616)"; + "failover:(tcp://127.0.0.1:61616)"; + + //============================================================ + // This is the Destination Name and URI options. Use this to + // customize where the consumer listens, to have the consumer + // use a topic or queue set the 'useTopics' flag. + //============================================================ + std::string destURI = "TEST.FOO"; //?consumer.prefetchSize=1"; + + //============================================================ + // set to true to use topics instead of queues + // Note in the code above that this causes createTopic or + // createQueue to be used in the consumer. + //============================================================ + bool useTopics = false; + + //============================================================ + // set to true if you want the consumer to use client ack mode + // instead of the default auto ack mode. + //============================================================ + bool clientAck = false; + + // Create the consumer + TAMQ_Consumer consumer(brokerURI, destURI, useTopics, clientAck); + + // Start it up and it will listen forever. + consumer.runConsumer(); + + // Wait to exit. + std::cout << "Press 'q' to quit" << std::endl; + while (std::cin.get() != 'q') { + } + + // All CMS resources should be closed before the library is shutdown. + consumer.close(); + + std::cout << "-----------------------------------------------------\n"; + std::cout << "Finished with the example." << std::endl; + std::cout << "=====================================================\n"; + + activemq::library::ActiveMQCPP::shutdownLibrary(); } \ No newline at end of file diff --git a/src/ER_V/acl/acl.c b/src/ER_V/acl/acl.c index 67cccff..d33ac60 100644 --- a/src/ER_V/acl/acl.c +++ b/src/ER_V/acl/acl.c @@ -1,311 +1,307 @@ -#include +#include "acl/acl.h" + #include -#include #include +#include +#include -#include "acl/acl.h" #include "acl/acl_private.h" -#include "util/comm.h" -#include "log/log.h" #include "erv_arm/erv.h" +#include "log/log.h" +#include "util/comm.h" -#define LOG_CONSOLE_THRESHOLD_THIS LOG_THRESHOLD_DEFAULT -#define LOG_FILE_THRESHOLD_THIS LOG_THRESHOLD_MAX +#define LOG_CONSOLE_THRESHOLD_THIS LOG_THRESHOLD_DEFAULT +#define LOG_FILE_THRESHOLD_THIS LOG_THRESHOLD_MAX ACL_Resources resources; -int ACL_Command_init(ACL_Command *cmd) -{ - if (!cmd) STD_FAIL; +int ACL_Command_init(ACL_Command *cmd) { + if (!cmd) STD_FAIL; - memset(cmd, 0, sizeof(ACL_Command)); + memset(cmd, 0, sizeof(ACL_Command)); - DATA_S_List_Node_init(&cmd->node); - DATA_S_List_append(&resources.free_queue, &cmd->node); + DATA_S_List_Node_init(&cmd->node); + DATA_S_List_append(&resources.free_queue, &cmd->node); - cmd->delay_ms = ACL_DEFAULT_COMMAND_DELAY_MS; + cmd->delay_ms = ACL_DEFAULT_COMMAND_DELAY_MS; - return 1; + return 1; } -int ACL_init() -{ - memset(&resources, 0, sizeof(resources)); - resources.cmd_pool = (ACL_Command*) malloc (ACL_CMD_COUNT * sizeof(ACL_Command)); - resources.cmd_count = ACL_CMD_COUNT; +int ACL_init() { + memset(&resources, 0, sizeof(resources)); + resources.cmd_pool = + (ACL_Command *)malloc(ACL_CMD_COUNT * sizeof(ACL_Command)); + resources.cmd_count = ACL_CMD_COUNT; - for(uint16_t iter = 0; iter < ACL_CMD_COUNT; iter++) - { - ACL_Command_init(&resources.cmd_pool[iter]); - } + for (uint16_t iter = 0; iter < ACL_CMD_COUNT; iter++) { + ACL_Command_init(&resources.cmd_pool[iter]); + } - resources.manaul_mode = 0; // Default is not manual mode - return 0; + resources.manaul_mode = 0; // Default is not manual mode + return 0; } +int ACL_destroy() { + DATA_S_List_deinit(&resources.free_queue); + resources.cmd_count = 0; + if (resources.cmd_pool) { + free(resources.cmd_pool); + resources.cmd_pool = NULL; + } -int ACL_destroy() -{ - DATA_S_List_deinit(&resources.free_queue); - resources.cmd_count = 0; - if (resources.cmd_pool) - { - free(resources.cmd_pool); - resources.cmd_pool = NULL; - } - - return 0; + return 0; } /** * @brief Helper function for fetching initialized ACL Command structs * @returns ACL Command pointer on success, NULL on failure -*/ -static ACL_Command* get_cmd(S_List *cmd_queue) -{ - if (!cmd_queue) STD_FAIL_VOID_PTR; - S_List_Node* node = DATA_S_List_pop(&resources.free_queue); - if (!node) STD_FAIL_VOID_PTR; - return DATA_LIST_GET_OBJ(node, ACL_Command, node); + */ +static ACL_Command *get_cmd(S_List *cmd_queue) { + if (!cmd_queue) STD_FAIL_VOID_PTR; + S_List_Node *node = DATA_S_List_pop(&resources.free_queue); + if (!node) STD_FAIL_VOID_PTR; + return DATA_LIST_GET_OBJ(node, ACL_Command, node); } -int ACL_flush_tx(S_List *cmd_queue) -{ - ACL_Command* cmd = get_cmd(cmd_queue); - if(!cmd) STD_FAIL; +int ACL_flush_tx(S_List *cmd_queue) { + ACL_Command *cmd = get_cmd(cmd_queue); + if (!cmd) STD_FAIL; - cmd->type = ACL_CMD_FLUSH; - cmd->len = sprintf(&cmd->payload[0], "\r"); - cmd->delay_ms = 100; + cmd->type = ACL_CMD_FLUSH; + cmd->len = sprintf(&cmd->payload[0], "\r"); + cmd->delay_ms = 100; - DATA_S_List_append(cmd_queue, &cmd->node); - return 0; + DATA_S_List_append(cmd_queue, &cmd->node); + return 0; } -int ACL_enqueue_clrbuf_cmd(S_List *cmd_queue) -{ - ACL_Command* cmd = get_cmd(cmd_queue); - if(!cmd) STD_FAIL; +int ACL_enqueue_clrbuf_cmd(S_List *cmd_queue) { + ACL_Command *cmd = get_cmd(cmd_queue); + if (!cmd) STD_FAIL; - cmd->type = ACL_CMD_ABORT; - cmd->len = sprintf(&cmd->payload[0], ACL_CLRBUF_FMT); - cmd->delay_ms = 100; + cmd->type = ACL_CMD_ABORT; + cmd->len = sprintf(&cmd->payload[0], ACL_CLRBUF_FMT); + cmd->delay_ms = 100; - DATA_S_List_append(cmd_queue, &cmd->node); - return 0; + DATA_S_List_append(cmd_queue, &cmd->node); + return 0; } -int ACL_enqueue_manual_mode_toggle_cmd(S_List *cmd_queue) -{ - ACL_Command* cmd = get_cmd(cmd_queue); - if(!cmd) STD_FAIL; +int ACL_enqueue_manual_mode_toggle_cmd(S_List *cmd_queue) { + ACL_Command *cmd = get_cmd(cmd_queue); + if (!cmd) STD_FAIL; - cmd->type = ACL_CMD_MANUAL; - cmd->len = sprintf(&cmd->payload[0], ACL_TOGGLE_MANUAL_FMT); + cmd->type = ACL_CMD_MANUAL; + cmd->len = sprintf(&cmd->payload[0], ACL_TOGGLE_MANUAL_FMT); - DATA_S_List_append(cmd_queue, &cmd->node); - return 0; + DATA_S_List_append(cmd_queue, &cmd->node); + return 0; } -char ACL_get_polar_pan_continuous_vector(API_Data_Polar_Pan_Start* payload) -{ - if (!payload) STD_FAIL; - - ACL_Manual_Axis vector; - if (payload->delta_azimuth) - { - vector = payload->delta_azimuth > 0 ? ACL_MAN_POS_BASE_AXIS : ACL_MAN_NEG_BASE_AXIS; - } - else if (payload->delta_altitude) - { - vector = payload->delta_altitude > 0 ? ACL_MAN_POS_WRIST_PITCH_AXIS : ACL_MAN_NEG_WRIST_PITCH_AXIS; - } - else - { - // LOG_IEC(); // A directionless start should not be issued - return '\0'; - } - - return (char) vector; +char ACL_get_polar_pan_continuous_vector(API_Data_Polar_Pan_Start *payload) { + if (!payload) STD_FAIL; + + ACL_Manual_Axis vector; + if (payload->delta_azimuth) { + vector = payload->delta_azimuth > 0 ? ACL_MAN_POS_BASE_AXIS + : ACL_MAN_NEG_BASE_AXIS; + } else if (payload->delta_altitude) { + vector = payload->delta_altitude > 0 ? ACL_MAN_POS_WRIST_PITCH_AXIS + : ACL_MAN_NEG_WRIST_PITCH_AXIS; + } else { + // LOG_IEC(); // A directionless start should not be issued + return '\0'; + } + + return (char)vector; } -int ACL_enqueue_shift_cmd(S_List *cmd_queue, ACL_Axis axis, float degree_count) -{ - ACL_Command* cmd = get_cmd(cmd_queue); - if(!cmd) STD_FAIL; +int ACL_enqueue_shift_cmd(S_List *cmd_queue, ACL_Axis axis, + float degree_count) { + ACL_Command *cmd = get_cmd(cmd_queue); + if (!cmd) STD_FAIL; - int encoder_count; + int encoder_count; - float conversion_factor; + float conversion_factor; - switch (axis) - { - case ACL_AXIS_BASE: - conversion_factor = ACL_BASE_CONVERSION_FACTOR; - break; + switch (axis) { + case ACL_AXIS_BASE: + conversion_factor = ACL_BASE_CONVERSION_FACTOR; + break; - case ACL_AXIS_WRIST_PITCH: - conversion_factor = ACL_WRIST_CONVERSION_FACTOR; - break; + case ACL_AXIS_WRIST_PITCH: + conversion_factor = ACL_WRIST_CONVERSION_FACTOR; + break; - default: - LOG_WARN("Degree -> Encoder Count Conversion Failed."); - STD_FAIL; - } + default: + LOG_WARN("Degree -> Encoder Count Conversion Failed."); + STD_FAIL; + } - encoder_count = (int)(degree_count * conversion_factor); + encoder_count = (int)(degree_count * conversion_factor); - cmd->len = sprintf(&cmd->payload[0], ACL_SHIFT_FMT, ACL_VAR_POS, axis, encoder_count); - cmd->type = ACL_CMD_SHIFT; + cmd->len = sprintf(&cmd->payload[0], ACL_SHIFT_FMT, ACL_VAR_POS, axis, + encoder_count); + cmd->type = ACL_CMD_SHIFT; - DATA_S_List_append(cmd_queue, &cmd->node); + DATA_S_List_append(cmd_queue, &cmd->node); - return 0; + return 0; } -int ACL_enqueue_here_cmd(S_List *cmd_queue) -{ - ACL_Command* cmd = get_cmd(cmd_queue); - if(!cmd) STD_FAIL; +int ACL_enqueue_here_cmd(S_List *cmd_queue) { + ACL_Command *cmd = get_cmd(cmd_queue); + if (!cmd) STD_FAIL; - cmd->len = sprintf(&cmd->payload[0], ACL_HERE_FMT, ACL_VAR_POS); - cmd->type = ACL_CMD_HERE; + cmd->len = sprintf(&cmd->payload[0], ACL_HERE_FMT, ACL_VAR_POS); + cmd->type = ACL_CMD_HERE; - DATA_S_List_append(cmd_queue, &cmd->node); + DATA_S_List_append(cmd_queue, &cmd->node); - return 0; + return 0; } -int ACL_enqueue_delay(S_List *cmd_queue, uint16_t delay_ms) -{ - ACL_Command* cmd = get_cmd(cmd_queue); - if(!cmd) STD_FAIL; +int ACL_enqueue_delay(S_List *cmd_queue, uint16_t delay_ms) { + ACL_Command *cmd = get_cmd(cmd_queue); + if (!cmd) STD_FAIL; - cmd->len = 0; - cmd->type = ACL_CMD_DELAY; - cmd->delay_ms = delay_ms; + cmd->len = 0; + cmd->type = ACL_CMD_DELAY; + cmd->delay_ms = delay_ms; - DATA_S_List_append(cmd_queue, &cmd->node); - return 0; + DATA_S_List_append(cmd_queue, &cmd->node); + return 0; } -int ACL_enqueue_move_cmd(S_List *cmd_queue) -{ - ACL_Command* cmd = get_cmd(cmd_queue); - if(!cmd) STD_FAIL; +int ACL_enqueue_move_cmd(S_List *cmd_queue) { + ACL_Command *cmd = get_cmd(cmd_queue); + if (!cmd) STD_FAIL; - cmd->len = sprintf(&cmd->payload[0], ACL_MOVE_FMT, ACL_VAR_POS); - cmd->type = ACL_CMD_MOVE; + cmd->len = sprintf(&cmd->payload[0], ACL_MOVE_FMT, ACL_VAR_POS); + cmd->type = ACL_CMD_MOVE; - DATA_S_List_append(cmd_queue, &cmd->node); - return 0; + DATA_S_List_append(cmd_queue, &cmd->node); + return 0; } -int ACL_generate_enqueue_moved_cmd(S_List *cmd_queue) -{ - ACL_Command* cmd = get_cmd(cmd_queue); - if(!cmd) STD_FAIL; +int ACL_generate_enqueue_moved_cmd(S_List *cmd_queue) { + ACL_Command *cmd = get_cmd(cmd_queue); + if (!cmd) STD_FAIL; - cmd->len = sprintf(&cmd->payload[0], ACL_MOVED_FMT, ACL_VAR_POS); - cmd->type = ACL_CMD_MOVE; + cmd->len = sprintf(&cmd->payload[0], ACL_MOVED_FMT, ACL_VAR_POS); + cmd->type = ACL_CMD_MOVE; - DATA_S_List_append(cmd_queue, &cmd->node); - return 0; + DATA_S_List_append(cmd_queue, &cmd->node); + return 0; } -int ACL_generate_enqueue_home_cmd(S_List *cmd_queue) -{ - ACL_Command* cmd = get_cmd(cmd_queue); - if(!cmd) STD_FAIL; +int ACL_generate_enqueue_home_cmd(S_List *cmd_queue) { + ACL_Command *cmd = get_cmd(cmd_queue); + if (!cmd) STD_FAIL; - cmd->len = sprintf(&cmd->payload[0], ACL_HOME_FMT); - cmd->type = ACL_CMD_HOME; - // cmd->delay_ms = ACL_DEFAULT_HOME_DELAY_MS; + cmd->len = sprintf(&cmd->payload[0], ACL_HOME_FMT); + cmd->type = ACL_CMD_HOME; + // cmd->delay_ms = ACL_DEFAULT_HOME_DELAY_MS; - DATA_S_List_append(cmd_queue, &cmd->node); - return 0; + DATA_S_List_append(cmd_queue, &cmd->node); + return 0; } -int ACL_generate_enqueue_defp_cmd(S_List *cmd_queue) -{ - ACL_Command* cmd = get_cmd(cmd_queue); - if(!cmd) STD_FAIL; +int ACL_generate_enqueue_defp_cmd(S_List *cmd_queue) { + ACL_Command *cmd = get_cmd(cmd_queue); + if (!cmd) STD_FAIL; - cmd->len = sprintf(&cmd->payload[0], ACL_DEFP_FMT, ACL_VAR_POS); - cmd->type = ACL_CMD_DEFP; + cmd->len = sprintf(&cmd->payload[0], ACL_DEFP_FMT, ACL_VAR_POS); + cmd->type = ACL_CMD_DEFP; - DATA_S_List_append(cmd_queue, &cmd->node); - return 0; + DATA_S_List_append(cmd_queue, &cmd->node); + return 0; } /** - * @brief Helper function for populating a Command Queue with the movements required for a polar pan + * @brief Helper function for populating a Command Queue with the movements + * required for a polar pan * @param cmd_queue Command Queue to append to * @param pan Polar pan parameters -*/ -static void polar_pan_body(S_List *cmd_queue, const API_Data_Polar_Pan *pan) -{ - if (pan->delta_azimuth != 0) - { - LOG_VERBOSE(4, "Converting Delta Azimuth"); - ACL_enqueue_shift_cmd(cmd_queue, ACL_AXIS_BASE, pan->delta_azimuth); - } - - if (pan->delta_altitude != 0) - { - LOG_VERBOSE(4, "Converting Delta Altitude"); - ACL_enqueue_shift_cmd(cmd_queue, ACL_AXIS_WRIST_PITCH, pan->delta_altitude); - } + */ +static void polar_pan_body(S_List *cmd_queue, const API_Data_Polar_Pan *pan) { + if (pan->delta_azimuth != 0) { + LOG_VERBOSE(4, "Converting Delta Azimuth"); + ACL_enqueue_shift_cmd(cmd_queue, ACL_AXIS_BASE, pan->delta_azimuth); + } + + if (pan->delta_altitude != 0) { + LOG_VERBOSE(4, "Converting Delta Altitude"); + ACL_enqueue_shift_cmd(cmd_queue, ACL_AXIS_WRIST_PITCH, pan->delta_altitude); + } } -int ACL_convert_polar_pan_abort(S_List *cmd_queue, const API_Data_Polar_Pan *pan) -{ - if (!cmd_queue) STD_FAIL; - if (!pan) STD_FAIL; +int ACL_convert_polar_pan_abort(S_List *cmd_queue, + const API_Data_Polar_Pan *pan) { + if (!cmd_queue) STD_FAIL; + if (!pan) STD_FAIL; - LOG_VERBOSE(4, "Converting polar pan abort command to ACL"); + LOG_VERBOSE(4, "Converting polar pan abort command to ACL"); - ACL_enqueue_here_cmd(cmd_queue); - polar_pan_body(cmd_queue, pan); - ACL_enqueue_clrbuf_cmd(cmd_queue); - ACL_enqueue_move_cmd(cmd_queue); + ACL_enqueue_here_cmd(cmd_queue); + polar_pan_body(cmd_queue, pan); + ACL_enqueue_clrbuf_cmd(cmd_queue); + ACL_enqueue_move_cmd(cmd_queue); - return 0; + return 0; } -int ACL_convert_polar_pan_direct(S_List *cmd_queue, const API_Data_Polar_Pan *pan) -{ - if (!cmd_queue) STD_FAIL; - if (!pan) STD_FAIL; +int ACL_convert_polar_pan_direct(S_List *cmd_queue, + const API_Data_Polar_Pan *pan) { + if (!cmd_queue) STD_FAIL; + if (!pan) STD_FAIL; - LOG_VERBOSE(4, "Converting polar pan direct command to ACL"); + LOG_VERBOSE(4, "Converting polar pan direct command to ACL"); - polar_pan_body(cmd_queue, pan); - ACL_enqueue_move_cmd(cmd_queue); + polar_pan_body(cmd_queue, pan); + ACL_enqueue_move_cmd(cmd_queue); - return 0; + return 0; } -int ACL_convert_polar_pan_ignore(S_List *cmd_queue, const API_Data_Polar_Pan *pan) -{ - if (!cmd_queue) STD_FAIL; - if (!pan) STD_FAIL; +int ACL_convert_polar_pan_ignore(S_List *cmd_queue, + const API_Data_Polar_Pan *pan) { + if (!cmd_queue) STD_FAIL; + if (!pan) STD_FAIL; + + LOG_VERBOSE(4, "Converting polar pan ignore command to ACL"); + + polar_pan_body(cmd_queue, pan); + ACL_enqueue_move_cmd(cmd_queue); + + return 0; +} - LOG_VERBOSE(4, "Converting polar pan ignore command to ACL"); +int ACL_home_sequence(S_List *cmd_queue) { + if (!cmd_queue) STD_FAIL; - polar_pan_body(cmd_queue, pan); - ACL_enqueue_move_cmd(cmd_queue); + ACL_generate_enqueue_defp_cmd(cmd_queue); + ACL_generate_enqueue_home_cmd(cmd_queue); + ACL_enqueue_here_cmd(cmd_queue); - return 0; + return 0; } -int ACL_home_sequence(S_List *cmd_queue) -{ - if (!cmd_queue) STD_FAIL; +int ACL_set_speed(S_List *cmd_queue, API_Data_Set_Speed *speed) { + if (!cmd_queue) STD_FAIL; + if (!speed) STD_FAIL; + + if (speed->speed > 100) speed->speed = 100; + + ACL_Command *cmd = get_cmd(cmd_queue); + if (!cmd) STD_FAIL; - ACL_generate_enqueue_defp_cmd(cmd_queue); - ACL_generate_enqueue_home_cmd(cmd_queue); - ACL_enqueue_here_cmd(cmd_queue); + cmd->len = sprintf(&cmd->payload[0], ACL_SPEED_FMT, speed->speed); + cmd->type = ACL_CMD_SPEED; - return 0; -} \ No newline at end of file + DATA_S_List_append(cmd_queue, &cmd->node); + + return 0; +} diff --git a/src/ER_V/acl/acl.h b/src/ER_V/acl/acl.h index c7f8b20..4c320dc 100644 --- a/src/ER_V/acl/acl.h +++ b/src/ER_V/acl/acl.h @@ -1,8 +1,9 @@ /** * ACL Conversion Module * - * This module is responsible for the conversion of received movement commands to ACL - * ACL is the programming language we use to communicate with the Scorbot-ER V + * This module is responsible for the conversion of received movement commands + * to ACL ACL is the programming language we use to communicate with the + * Scorbot-ER V */ #pragma once @@ -20,37 +21,39 @@ #define ACL_DEV_BYTES_PER_SEC (ACL_DEV_BAUD / ACL_DEV_FRAME_SIZE) /** (Bytes_s * delay_us) / (10^6) */ -// #define ACL_BYTES_PER_DELAY ((ACL_DEFAULT_COMMAND_DELAY_MS) * (ACL_DEV_BYTES_PER_SEC) / (1000 * 1000)) +// #define ACL_BYTES_PER_DELAY ((ACL_DEFAULT_COMMAND_DELAY_MS) * +// (ACL_DEV_BYTES_PER_SEC) / (1000 * 1000)) #define ACL_MANUAL_MOVE_SIZE 1 /** ACL Command Types */ -typedef enum _acl_command_type -{ - ACL_CMD_INVALID, - ACL_CMD_DELAY, - ACL_CMD_FLUSH, - ACL_CMD_ABORT, - ACL_CMD_DEFP, - ACL_CMD_HERE, - ACL_CMD_SHIFT, - ACL_CMD_MANUAL, - ACL_CMD_HOME, - ACL_CMD_MOVE, +typedef enum _acl_command_type { + ACL_CMD_INVALID, + ACL_CMD_DELAY, + ACL_CMD_FLUSH, + ACL_CMD_ABORT, + ACL_CMD_DEFP, + ACL_CMD_HERE, + ACL_CMD_SHIFT, + ACL_CMD_MANUAL, + ACL_CMD_HOME, + ACL_CMD_MOVE, + ACL_CMD_SPEED } ACL_Command_Type; /** ACL Command Map for the command string, length, and node */ -typedef struct _acl_command -{ - char payload[ACL_CMD_SIZE]; /** The ACL command (dynamically sized)*/ - uint8_t len; /** The length of the ACL command */ - ACL_Command_Type type; /** ACL command type */ - uint16_t delay_ms; /** Milliseconds between this command and the next command */ - S_List_Node node; /** The node of the s_list */ +typedef struct _acl_command { + char payload[ACL_CMD_SIZE]; /** The ACL command (dynamically sized)*/ + uint8_t len; /** The length of the ACL command */ + ACL_Command_Type type; /** ACL command type */ + uint16_t + delay_ms; /** Milliseconds between this command and the next command */ + S_List_Node node; /** The node of the s_list */ } ACL_Command; /** * @brief Allocates memory for an ACL_Resource's array of ACL_Commands - * @details Iterates through command pool in global ACL_Resources and populates with dummy data + * @details Iterates through command pool in global ACL_Resources and populates + * with dummy data * @returns 0 on success, -1 on failure */ int ACL_init(); @@ -58,20 +61,23 @@ int ACL_init(); /** * @brief Clears the tx buffer to the Scorbot to ensure a blank slate * @details Used on startup to clear unknown state of scorbot serial receiver - * @param cmd_queue S_List pointer to be manipulated into a queue of ACL Commands + * @param cmd_queue S_List pointer to be manipulated into a queue of ACL + * Commands * @returns 0 on success, -1 on failure -*/ + */ int ACL_flush_tx(S_List *cmd_queue); /** * @brief Dellocates memory for an ACL_Resource's array of ACL_Commands - * @details Iterates through command pool in global ACL_Resources and populates with dummy data + * @details Iterates through command pool in global ACL_Resources and populates + * with dummy data * @returns 0 on success, -1 on failure */ int ACL_destroy(); /** - * @brief Allocates memory for a single ACL_Command and initializes its S_List node + * @brief Allocates memory for a single ACL_Command and initializes its S_List + * node * @details Fills the input cmd with dummy data in the form of 0's * Initializes cmd's S_List_Node; appends node to global resource's S_List * @param cmd ACL_Command to initialize @@ -80,40 +86,51 @@ int ACL_destroy(); int ACL_Command_init(ACL_Command *cmd); /** - * @brief Populates cmd_queue with a formatted queue for executing a polar pan, according to contents of pan. Aborts last movement (not cummulative). - * @details Polar Pan command struct is processed and turned into a set of ACL commands - * ACL Commands are stored in the input empty S_List - * @param cmd_queue S_List pointer to be manipulated into a queue of ACL Commands + * @brief Populates cmd_queue with a formatted queue for executing a polar pan, + * according to contents of pan. Aborts last movement (not cummulative). + * @details Polar Pan command struct is processed and turned into a set of ACL + * commands ACL Commands are stored in the input empty S_List + * @param cmd_queue S_List pointer to be manipulated into a queue of ACL + * Commands * @param pan Polar Pan command struct pointer * @returns 0 on success, -1 on failure */ -int ACL_convert_polar_pan_abort(S_List *cmd_queue, const API_Data_Polar_Pan *pan); +int ACL_convert_polar_pan_abort(S_List *cmd_queue, + const API_Data_Polar_Pan *pan); /** - * @brief Populates cmd_queue with a formatted queue for executing a polar pan, according to contents of pan. Accumlates onto last movement command - * @details Polar Pan command struct is processed and turned into a set of ACL commands - * ACL Commands are stored in the input empty S_List - * @param cmd_queue S_List pointer to be manipulated into a queue of ACL Commands + * @brief Populates cmd_queue with a formatted queue for executing a polar pan, + * according to contents of pan. Accumlates onto last movement command + * @details Polar Pan command struct is processed and turned into a set of ACL + * commands ACL Commands are stored in the input empty S_List + * @param cmd_queue S_List pointer to be manipulated into a queue of ACL + * Commands * @param pan Polar Pan command struct pointer * @returns 0 on success, -1 on failure */ -int ACL_convert_polar_pan_direct(S_List *cmd_queue, const API_Data_Polar_Pan *pan); +int ACL_convert_polar_pan_direct(S_List *cmd_queue, + const API_Data_Polar_Pan *pan); /** - * @brief Populates cmd_queue with a formatted queue for executing a polar pan, according to contents of pan. Drops movements while the current one is finishing. - * @details Polar Pan command struct is processed and turned into a set of ACL commands - * ACL Commands are stored in the input empty S_List - * @param cmd_queue S_List pointer to be manipulated into a queue of ACL Commands + * @brief Populates cmd_queue with a formatted queue for executing a polar pan, + * according to contents of pan. Drops movements while the current one is + * finishing. + * @details Polar Pan command struct is processed and turned into a set of ACL + * commands ACL Commands are stored in the input empty S_List + * @param cmd_queue S_List pointer to be manipulated into a queue of ACL + * Commands * @param pan Polar Pan command struct pointer * @returns 0 on success, -1 on failure */ -int ACL_convert_polar_pan_ignore(S_List *cmd_queue, const API_Data_Polar_Pan *pan); +int ACL_convert_polar_pan_ignore(S_List *cmd_queue, + const API_Data_Polar_Pan *pan); /** - * @brief Populates cmd_queue with a formatted queue for toggle manual mode on the controller unit + * @brief Populates cmd_queue with a formatted queue for toggle manual mode on + * the controller unit * @details Only works when the Scorbot ER V controller is in DIRECT mode * @returns 0 on success, -1 on failure -*/ + */ int ACL_enqueue_manual_mode_toggle_cmd(S_List *cmd_queue); /** @@ -132,14 +149,22 @@ int ACL_enqueue_here_cmd(S_List *cmd_queue); int ACL_enqueue_delay(S_List *cmd_queue, uint16_t delay_ms); /** - * @brief Generates and enqueues a home command and sets ACL_VAR_POS as the movable variable + * @brief Generates and enqueues a home command and sets ACL_VAR_POS as the + * movable variable * @param cmd_queue The command queue to fill * @returns 0 on success, -1 on failure */ int ACL_home_sequence(S_List *cmd_queue); /** - * @brief Returns the ACL character corresponding to the desired angular vector, according to the received payload + * @brief Generates and enqueues a move command to the command queue + * @param cmd_queue The command queue to fill + * @returns 0 on success, -1 on failure + */ +int ACL_set_speed(S_List *cmd_queue, API_Data_Set_Speed *speed); +/** + * @brief Returns the ACL character corresponding to the desired angular vector, + * according to the received payload * @returns Corresponding ACL character on success, NULL character on failure -*/ -char ACL_get_polar_pan_continuous_vector(API_Data_Polar_Pan_Start* payload); + */ +char ACL_get_polar_pan_continuous_vector(API_Data_Polar_Pan_Start *payload); diff --git a/src/ER_V/acl/acl_private.h b/src/ER_V/acl/acl_private.h index 595816d..6c62a6c 100644 --- a/src/ER_V/acl/acl_private.h +++ b/src/ER_V/acl/acl_private.h @@ -10,56 +10,71 @@ #define ACL_CMD_COUNT 1024 /** ACL Command Formats */ -#define ACL_ABORT_FMT "A\r" // Aborts the current movment (but keeps the movement buffer in tact) -#define ACL_SHIFT_FMT "SHIFT %s BY %u %d\r" // Shift command to move a variable the Scorbot has stored -#define ACL_HERE_FMT "HERE %s\r" // Here command to set the input Scorbot position to its current position -#define ACL_MOVE_FMT "MOVE %s\r" // Move command to move to a set point -#define ACL_MOVE_DUR_FMT "MOVE %s %u\r" // Move command to move to a set point, within a specific duration -#define ACL_MOVED_FMT "MOVED %s\r" // Move command to move to a set point -#define ACL_MOVED_DUR_FMT "MOVED %s %u\r" // Move command to move to a set point, within a specific duration -#define ACL_HOME_FMT "HOME\r" // Home command homes the robot -#define ACL_DEFP_FMT "DEFP %s\r" // Defp command sets an internal variable to the current position for Scorbot -#define ACL_TOGGLE_MANUAL_FMT "~" // While the scorbot controller is in direct mode, this command allows manual control of the position (like a joystick) -#define ACL_MOVE_MANUAL_FMT "%c" -#define ACL_CLRBUF_FMT "clrbuf\r" // Clears the movement buffer, and halts all motor movement +#define ACL_ABORT_FMT \ + "A\r" // Aborts the current movment (but keeps the movement buffer in tact) +#define ACL_SHIFT_FMT \ + "SHIFT %s BY %u %d\r" // Shift command to move a variable the Scorbot has + // stored +#define ACL_HERE_FMT \ + "HERE %s\r" // Here command to set the input Scorbot position to its current + // position +#define ACL_MOVE_FMT "MOVE %s\r" // Move command to move to a set point +#define ACL_MOVE_DUR_FMT \ + "MOVE %s %u\r" // Move command to move to a set point, within a specific + // duration +#define ACL_MOVED_FMT "MOVED %s\r" // Move command to move to a set point +#define ACL_MOVED_DUR_FMT \ + "MOVED %s %u\r" // Move command to move to a set point, within a specific + // duration +#define ACL_HOME_FMT "HOME\r" // Home command homes the robot +#define ACL_SPEED_FMT "SPEED %u\r" // Speed command sets the speed of the robot +#define ACL_DEFP_FMT \ + "DEFP %s\r" // Defp command sets an internal variable to the current position + // for Scorbot +#define ACL_TOGGLE_MANUAL_FMT \ + "~" // While the scorbot controller is in direct mode, this command allows + // manual control of the position (like a joystick) +#define ACL_MOVE_MANUAL_FMT "%c" +#define ACL_CLRBUF_FMT \ + "clrbuf\r" // Clears the movement buffer, and halts all motor movement /** Scorbot axes representation in ACL */ -typedef enum _acl_axis -{ - ACL_AXIS_BASE = 1, - ACL_AXIS_SHOULDER = 2, - ACL_AXIS_ELBOW = 3, - ACL_AXIS_WRIST_PITCH = 4, - ACL_AXIS_WRIST_ROLL = 5 +typedef enum _acl_axis { + ACL_AXIS_BASE = 1, + ACL_AXIS_SHOULDER = 2, + ACL_AXIS_ELBOW = 3, + ACL_AXIS_WRIST_PITCH = 4, + ACL_AXIS_WRIST_ROLL = 5 } ACL_Axis; -typedef enum _acl_manual_axis -{ - ACL_MAN_POS_BASE_AXIS = '1', - ACL_MAN_NEG_BASE_AXIS = 'q', - ACL_MAN_POS_SHOULDER_AXIS = '2', - ACL_MAN_NEG_SHOULDER_AXIS = 'w', - ACL_MAN_POS_ELBOW_AXIS = '3', - ACL_MAN_NEG_ELBOW_AXIS = 'e', - ACL_MAN_POS_WRIST_PITCH_AXIS = '4', - ACL_MAN_NEG_WRIST_PITCH_AXIS = 'r', - ACL_MAN_POS_WRIST_ROLL_AXIS = '5', - ACL_MAN_NEG_WRIST_ROLL_AXIS = 't', +typedef enum _acl_manual_axis { + ACL_MAN_POS_BASE_AXIS = '1', + ACL_MAN_NEG_BASE_AXIS = 'q', + ACL_MAN_POS_SHOULDER_AXIS = '2', + ACL_MAN_NEG_SHOULDER_AXIS = 'w', + ACL_MAN_POS_ELBOW_AXIS = '3', + ACL_MAN_NEG_ELBOW_AXIS = 'e', + ACL_MAN_POS_WRIST_PITCH_AXIS = '4', + ACL_MAN_NEG_WRIST_PITCH_AXIS = 'r', + ACL_MAN_POS_WRIST_ROLL_AXIS = '5', + ACL_MAN_NEG_WRIST_ROLL_AXIS = 't', } ACL_Manual_Axis; /** Resource management struct for ACL commands and the associated S_List */ -typedef struct _acl_resources -{ - // ACL_Command cmd_pool[ACL_CMD_COUNT]; /** Statically Allocated ACL_Command pool */ - ACL_Command* cmd_pool; /** Dynamically Allocated ACL_Command pool */ - uint32_t cmd_count; /** Number of ACL_Commands in cmd_pool */ - S_List free_queue; /** Queue of free ACL_Commands */ - uint8_t manaul_mode; /** Manual mode tracker */ +typedef struct _acl_resources { + // ACL_Command cmd_pool[ACL_CMD_COUNT]; /** Statically Allocated + // ACL_Command pool */ + ACL_Command *cmd_pool; /** Dynamically Allocated ACL_Command pool */ + uint32_t cmd_count; /** Number of ACL_Commands in cmd_pool */ + S_List free_queue; /** Queue of free ACL_Commands */ + uint8_t manaul_mode; /** Manual mode tracker */ } ACL_Resources; /** - * @brief Calculates encoder count and stores the proper ACL shift command payload - * @details Compares axes and stores the associated ACL command in the input ACL_Command struct + * @brief Calculates encoder count and stores the proper ACL shift command + * payload + * @details Compares axes and stores the associated ACL command in the input + * ACL_Command struct * @param cmd_queue S_List to fill with commands * @param axis Axis being manipulated on Scorbot * @param degree_count Amount of degrees to convert to Encoder Count @@ -79,6 +94,5 @@ int ACL_enqueue_move_cmd(S_List *cmd_queue); * @details Aborts all movement/running programs on the ER V controller * @param cmd_queue S_List to append to * @returns 0 on success, -1 on failure -*/ + */ int ACL_enqueue_clrbuf_cmd(S_List *cmd_queue); - diff --git a/src/ER_V/active_mq_client_demo.cpp b/src/ER_V/active_mq_client_demo.cpp index e42ea8d..0958ec2 100644 --- a/src/ER_V/active_mq_client_demo.cpp +++ b/src/ER_V/active_mq_client_demo.cpp @@ -15,82 +15,82 @@ * limitations under the License. */ -#include -#include -#include -#include #include -#include +#include #include -#include +#include #include -#include -#include -#include -#include #include -#include +#include #include +#include #include -#include +#include +#include +#include +#include +#include +#include +#include #include +#include + #include //////////////////////////////////////////////////////////////////////////////// -int main(int argc AMQCPP_UNUSED, char* argv[] AMQCPP_UNUSED) { - - activemq::library::ActiveMQCPP::initializeLibrary(); +int main(int argc AMQCPP_UNUSED, char *argv[] AMQCPP_UNUSED) { + activemq::library::ActiveMQCPP::initializeLibrary(); - std::cout << "=====================================================\n"; - std::cout << "Starting the example:" << std::endl; - std::cout << "-----------------------------------------------------\n"; + std::cout << "=====================================================\n"; + std::cout << "Starting the example:" << std::endl; + std::cout << "-----------------------------------------------------\n"; - // Set the URI to point to the IPAddress of your broker. - // add any optional params to the url to enable things like - // tightMarshalling or tcp logging etc. See the CMS web site for - // a full list of configuration options. - // - // http://activemq.apache.org/cms/ - // - std::string brokerURI = - "failover:(tcp://127.0.0.1:61616)"; + // Set the URI to point to the IPAddress of your broker. + // add any optional params to the url to enable things like + // tightMarshalling or tcp logging etc. See the CMS web site for + // a full list of configuration options. + // + // http://activemq.apache.org/cms/ + // + std::string brokerURI = "failover:(tcp://127.0.0.1:61616)"; - //============================================================ - // This is the Destination Name and URI options. Use this to - // customize where the consumer listens, to have the consumer - // use a topic or queue set the 'useTopics' flag. - //============================================================ - std::string destURI = "TEST.FOO"; //?consumer.prefetchSize=1"; + //============================================================ + // This is the Destination Name and URI options. Use this to + // customize where the consumer listens, to have the consumer + // use a topic or queue set the 'useTopics' flag. + //============================================================ + std::string destURI = "TEST.FOO"; //?consumer.prefetchSize=1"; - //============================================================ - // set to true to use topics instead of queues - // Note in the code above that this causes createTopic or - // createQueue to be used in the consumer. - //============================================================ - bool useTopics = false; + //============================================================ + // set to true to use topics instead of queues + // Note in the code above that this causes createTopic or + // createQueue to be used in the consumer. + //============================================================ + bool useTopics = false; - //============================================================ - // set to true if you want the consumer to use client ack mode - // instead of the default auto ack mode. - //============================================================ - bool clientAck = false; + //============================================================ + // set to true if you want the consumer to use client ack mode + // instead of the default auto ack mode. + //============================================================ + bool clientAck = false; - // Create the consumer - TAMQ_Consumer consumer( brokerURI, destURI, useTopics, clientAck ); + // Create the consumer + TAMQ_Consumer consumer(brokerURI, destURI, useTopics, clientAck); - // Start it up and it will listen forever. - consumer.runConsumer(); + // Start it up and it will listen forever. + consumer.runConsumer(); - // Wait to exit. - std::cout << "Press 'q' to quit" << std::endl; - while( std::cin.get() != 'q') {} + // Wait to exit. + std::cout << "Press 'q' to quit" << std::endl; + while (std::cin.get() != 'q') { + } - // All CMS resources should be closed before the library is shutdown. - consumer.close(); + // All CMS resources should be closed before the library is shutdown. + consumer.close(); - std::cout << "-----------------------------------------------------\n"; - std::cout << "Finished with the example." << std::endl; - std::cout << "=====================================================\n"; + std::cout << "-----------------------------------------------------\n"; + std::cout << "Finished with the example." << std::endl; + std::cout << "=====================================================\n"; - activemq::library::ActiveMQCPP::shutdownLibrary(); + activemq::library::ActiveMQCPP::shutdownLibrary(); } \ No newline at end of file diff --git a/src/ER_V/all_tests.cpp b/src/ER_V/all_tests.cpp index af3b808..6fe93ab 100644 --- a/src/ER_V/all_tests.cpp +++ b/src/ER_V/all_tests.cpp @@ -1,12 +1,8 @@ #include #include -TEST_GROUP(Group) {}; +TEST_GROUP(Group){}; -IGNORE_TEST(Group, Test) { -}; +IGNORE_TEST(Group, Test){}; -int main(int argc, char ** argv) -{ - RUN_ALL_TESTS(argc, argv); -} \ No newline at end of file +int main(int argc, char **argv) { RUN_ALL_TESTS(argc, argv); } \ No newline at end of file diff --git a/src/ER_V/api_demo.c b/src/ER_V/api_demo.c index 6a2a8fe..d252c02 100644 --- a/src/ER_V/api_demo.c +++ b/src/ER_V/api_demo.c @@ -1,107 +1,98 @@ +#include #include #include -#include #include -#include "util/comm.h" -#include "util/array.h" -#include "log/log.h" #include "api/api.h" +#include "log/log.h" #include "sub/sub.h" +#include "util/array.h" +#include "util/comm.h" - -#define LOG_FILE_THRESHOLD_THIS LOG_THRESHOLD_MAX -#define LOG_CONSOLE_THRESHOLD_THIS LOG_THRESHOLD_MAX - +#define LOG_FILE_THRESHOLD_THIS LOG_THRESHOLD_MAX +#define LOG_CONSOLE_THRESHOLD_THIS LOG_THRESHOLD_MAX /** * @brief Helper function for simulating incoming message header * @param header Command header to prepare -*/ -static void prep_header (API_Data_Header *header) -{ - header->cmd_id = htobe32(header->cmd_id); - header->cmd_val = htobe16(header->cmd_val); - header->len = htobe16(header->len); + */ +static void prep_header(API_Data_Header *header) { + header->cmd_id = htobe32(header->cmd_id); + header->cmd_val = htobe16(header->cmd_val); + header->len = htobe16(header->len); } /** * @brief Helper function for simulating incoming polar pan message * @param payload Payload to prep -*/ -static void prep_polar_pan (API_Data_Polar_Pan *payload) -{ - payload->delta_altitude = htobe32(payload->delta_altitude); - payload->delta_azimuth = htobe32(payload->delta_azimuth); - payload->delay_ms = htobe32(payload->delay_ms); - payload->time_ms = htobe32(payload->time_ms); + */ +static void prep_polar_pan(API_Data_Polar_Pan *payload) { + payload->delta_altitude = htobe32(payload->delta_altitude); + payload->delta_azimuth = htobe32(payload->delta_azimuth); + payload->delay_ms = htobe32(payload->delay_ms); + payload->time_ms = htobe32(payload->time_ms); } /** * @brief Helper function for simulating incoming command * @param cmd Command Wrapper -*/ -static void prep_polar_pan_wrapper (API_Data_Wrapper *cmd) -{ - prep_header(&cmd->header); - prep_polar_pan((API_Data_Polar_Pan*) &cmd->payload_head); + */ +static void prep_polar_pan_wrapper(API_Data_Wrapper *cmd) { + prep_header(&cmd->header); + prep_polar_pan((API_Data_Polar_Pan *)&cmd->payload_head); } /** * @brief fills byte array with simulated data * @param bytes Byte array -*/ -static void fill_simulated_command(uint8_t *bytes) -{ - - API_Data_Wrapper *cmd = (API_Data_Wrapper *) bytes; - API_Data_Header *header = (API_Data_Header *) &cmd->header; - API_Data_Polar_Pan *payload = (API_Data_Polar_Pan*) &cmd->payload_head; - - // Assign test values to header - header->cmd_id = 0xBE; - header->cmd_val = API_CMD_POLARPAN; - header->len = sizeof(API_Data_Polar_Pan); - - // Assign test values to body - payload->delta_azimuth = -1; - payload->delta_altitude = 0; - payload->delay_ms = 1; - payload->time_ms = 2; + */ +static void fill_simulated_command(uint8_t *bytes) { + API_Data_Wrapper *cmd = (API_Data_Wrapper *)bytes; + API_Data_Header *header = (API_Data_Header *)&cmd->header; + API_Data_Polar_Pan *payload = (API_Data_Polar_Pan *)&cmd->payload_head; + + // Assign test values to header + header->cmd_id = 0xBE; + header->cmd_val = API_CMD_POLARPAN; + header->len = sizeof(API_Data_Polar_Pan); + + // Assign test values to body + payload->delta_azimuth = -1; + payload->delta_altitude = 0; + payload->delay_ms = 1; + payload->time_ms = 2; } -int main() -{ - LOG_init(); - LOG_start(); - LOG_INFO("Staring demo..."); - - // Setup buffers - uint16_t byte_len = sizeof(API_Data_Header) + sizeof(API_Data_Polar_Pan) + 2; - uint8_t bytes[byte_len]; - memset(&bytes[0], 0, byte_len); - char text[UTIL_BYTE_STR_FMT_LEN(byte_len)]; - memset(&text[0], 0, UTIL_BYTE_STR_FMT_LEN(byte_len)); +int main() { + LOG_init(); + LOG_start(); + LOG_INFO("Staring demo..."); - // Prep simulated incoming message - fill_simulated_command(&bytes[0]); - API_Data_Wrapper *cmd = (API_Data_Wrapper*) &bytes[0]; - UTIL_format_byte_str(&text[0], &bytes[0], byte_len); - LOG_VERBOSE(4, "Init: %s", text); + // Setup buffers + uint16_t byte_len = sizeof(API_Data_Header) + sizeof(API_Data_Polar_Pan) + 2; + uint8_t bytes[byte_len]; + memset(&bytes[0], 0, byte_len); + char text[UTIL_BYTE_STR_FMT_LEN(byte_len)]; + memset(&text[0], 0, UTIL_BYTE_STR_FMT_LEN(byte_len)); - prep_polar_pan_wrapper(cmd); + // Prep simulated incoming message + fill_simulated_command(&bytes[0]); + API_Data_Wrapper *cmd = (API_Data_Wrapper *)&bytes[0]; + UTIL_format_byte_str(&text[0], &bytes[0], byte_len); + LOG_VERBOSE(4, "Init: %s", text); - UTIL_format_byte_str(&text[0], &bytes[0], byte_len); - LOG_VERBOSE(4, "Pre : %s", text); + prep_polar_pan_wrapper(cmd); - // process command using API module - if(API_validate_command(&bytes[0], byte_len)) LOG_IEC(); + UTIL_format_byte_str(&text[0], &bytes[0], byte_len); + LOG_VERBOSE(4, "Pre : %s", text); - UTIL_format_byte_str(&text[0], &bytes[0], byte_len); - LOG_VERBOSE(4, "Post: %s", text); + // process command using API module + if (API_validate_command(&bytes[0], byte_len)) LOG_IEC(); + UTIL_format_byte_str(&text[0], &bytes[0], byte_len); + LOG_VERBOSE(4, "Post: %s", text); - LOG_INFO("Demo Ending..."); - LOG_stop(); - LOG_destory(); + LOG_INFO("Demo Ending..."); + LOG_stop(); + LOG_destory(); } \ No newline at end of file diff --git a/src/ER_V/erv_arm/erv.cpp b/src/ER_V/erv_arm/erv.cpp index d642b1b..0861087 100644 --- a/src/ER_V/erv_arm/erv.cpp +++ b/src/ER_V/erv_arm/erv.cpp @@ -1,343 +1,346 @@ -#include -#include -#include -#include +#include "erv_arm/erv.h" + #include #include +#include +#include #include +#include +#include #include #include -#include +#include -#include "erv_arm/erv.h" -#include "log/log.h" #include "acl/acl.h" +#include "log/log.h" -#define LOG_CONSOLE_THRESHOLD_THIS LOG_THRESHOLD_DEFAULT -#define LOG_FILE_THRESHOLD_THIS LOG_THRESHOLD_MAX +#define LOG_CONSOLE_THRESHOLD_THIS LOG_THRESHOLD_DEFAULT +#define LOG_FILE_THRESHOLD_THIS LOG_THRESHOLD_MAX #define ERV_DEFAULT_COMMAND_DELAY 200000 #define ERV_TTY_BUFFER_LEN 127 #define ERV_CLOCK CLOCK_REALTIME -Scorbot::Scorbot(const char* dev) -{ - // Setup device - LOG_VERBOSE(4, "Scorbot device path: %s", dev); - strcpy(&this->dev[0], &dev[0]); - fd = open(dev, O_RDWR | O_NOCTTY | O_NDELAY); - if (fd < 0) - { - LOG_ERROR("Could not open Scorbot device path: %s", strerror(errno)); - raise(SIGABRT); - return; - } +Scorbot::Scorbot(const char *dev) { + // Setup device + LOG_VERBOSE(4, "Scorbot device path: %s", dev); + strcpy(&this->dev[0], &dev[0]); + fd = open(dev, O_RDWR | O_NOCTTY | O_NDELAY); + if (fd < 0) { + LOG_ERROR("Could not open Scorbot device path: %s", strerror(errno)); + raise(SIGABRT); + return; + } - // Setup config - polar_pan_cont = '\0'; - manual_mode = false; - oversteer = OVERSTEER_ABORT; + // Setup config + polar_pan_cont = '\0'; + manual_mode = false; + oversteer = OVERSTEER_ABORT; - // Setup ACL - ACL_init(); - DATA_S_List_init(&cmd_buffer); - gettimeofday(&last_start, NULL); + // Setup ACL + ACL_init(); + DATA_S_List_init(&cmd_buffer); + gettimeofday(&last_start, NULL); - ACL_flush_tx(&cmd_buffer); + ACL_flush_tx(&cmd_buffer); } -Scorbot::~Scorbot() -{ - if(-1 != fd && close(fd)) LOG_ERROR("Scorbot: Could not close device descriptor: %s", strerror(errno)); - ACL_destroy(); +Scorbot::~Scorbot() { + if (-1 != fd && close(fd)) + LOG_ERROR("Scorbot: Could not close device descriptor: %s", + strerror(errno)); + ACL_destroy(); } /** - * @brief Helper function that determines if a character is a line terminator for the Scorbot RX line + * @brief Helper function that determines if a character is a line terminator + * for the Scorbot RX line * @param ch Character to determine * @returns 1 if a terminating char, 0 otherwise. -*/ -static uint8_t is_term (char ch) -{ - switch (ch) - { - // Intentional fallthroughs - case '\r': - case '\n': - case '\0': - case '>': - return 1; - default: - break; - } - - return 0; + */ +static uint8_t is_term(char ch) { + switch (ch) { + // Intentional fallthroughs + case '\r': + case '\n': + case '\0': + case '>': + return 1; + default: + break; + } + + return 0; } /** - * @brief Flushes the receive buffer, starting from index 0, up to index length; Logs the flushed data + * @brief Flushes the receive buffer, starting from index 0, up to index length; + * Logs the flushed data * @details Assumes buffer length of ERV_TTY_BUFFER_LEN - * @param tty_buffer The buffer to flush; intended to be the static buffer storing the rx data + * @param tty_buffer The buffer to flush; intended to be the static buffer + * storing the rx data * @param len Number of chars to flush -*/ -static void flush_buffer(char* tty_buffer, uint16_t len) -{ - if (!tty_buffer) STD_FAIL_VOID; - if (!len) return; + */ +static void flush_buffer(char *tty_buffer, uint16_t len) { + if (!tty_buffer) STD_FAIL_VOID; + if (!len) return; - tty_buffer[ERV_TTY_BUFFER_LEN - 1] = '\0'; // Ensure end is null terminated - if (len + 1 < ERV_TTY_BUFFER_LEN) tty_buffer[len + 1] = '\0'; + tty_buffer[ERV_TTY_BUFFER_LEN - 1] = '\0'; // Ensure end is null terminated + if (len + 1 < ERV_TTY_BUFFER_LEN) tty_buffer[len + 1] = '\0'; - LOG_VERBOSE(0, "SCOR: %s", tty_buffer); + LOG_VERBOSE(0, "SCOR: %s", tty_buffer); } -static uint16_t tval_diff_ms(struct timeval* end, struct timeval* start) -{ - time_t start_ms = (start->tv_sec * 1000) + (start->tv_usec / 1000); - time_t end_ms = (end->tv_sec * 1000) + (end->tv_usec / 1000); - return end_ms - start_ms; +static uint16_t tval_diff_ms(struct timeval *end, struct timeval *start) { + time_t start_ms = (start->tv_sec * 1000) + (start->tv_usec / 1000); + time_t end_ms = (end->tv_sec * 1000) + (end->tv_usec / 1000); + return end_ms - start_ms; } /** - * @brief Helper function used to handle continuous polar pan commands during polling - * @details Continuous polar pan has to run in a loop, independent of the command bus, to allow asyncrounous commands. - * This allows the bus to not become overwhelmed. + * @brief Helper function used to handle continuous polar pan commands during + * polling + * @details Continuous polar pan has to run in a loop, independent of the + * command bus, to allow asyncrounous commands. This allows the bus to not + * become overwhelmed. * @param fd File descriptor for Scorbot ER V serial device - * @param polar_pan_cont Character describing the angular vector that the polar pan is executing - * @param manual_mode Pointer to the bool tracking the current mode of the controller -*/ -static void poll_polar_pan(int fd, char* polar_pan_cont, struct timeval *last_start, bool* manual_mode) -{ - static char last_pan_cont; - - struct timeval now; - gettimeofday(&now, NULL); - if (*polar_pan_cont && tval_diff_ms(&now, last_start) > ERV_CONT_POLAR_PAN_TIMEOUT_MS) - { - LOG_WARN("Continuous Polar Pan timeout"); - *polar_pan_cont = '\0'; + * @param polar_pan_cont Character describing the angular vector that the polar + * pan is executing + * @param manual_mode Pointer to the bool tracking the current mode of the + * controller + */ +static void poll_polar_pan(int fd, char *polar_pan_cont, + struct timeval *last_start, bool *manual_mode) { + static char last_pan_cont; + + struct timeval now; + gettimeofday(&now, NULL); + if (*polar_pan_cont && + tval_diff_ms(&now, last_start) > ERV_CONT_POLAR_PAN_TIMEOUT_MS) { + LOG_WARN("Continuous Polar Pan timeout"); + *polar_pan_cont = '\0'; + } + + if (last_pan_cont != *polar_pan_cont) { + // flush write buffer + tcflush(fd, TCOFLUSH); + if (!last_pan_cont || !*polar_pan_cont) { + // Manual mode is toggling + write(fd, "~", 1); + *manual_mode = !(*manual_mode); } + } - if (last_pan_cont != *polar_pan_cont) - { - //flush write buffer - tcflush(fd, TCOFLUSH); - if (!last_pan_cont || !*polar_pan_cont) - { - // Manual mode is toggling - write(fd, "~", 1); - *manual_mode = !(*manual_mode); - } - } + char manual[ACL_MANUAL_MOVE_SIZE]; + if (*polar_pan_cont) { + memset(&manual[0], *polar_pan_cont, sizeof(manual)); + write(fd, &manual, sizeof(manual)); + } - char manual[ACL_MANUAL_MOVE_SIZE]; - if (*polar_pan_cont) - { - memset(&manual[0], *polar_pan_cont, sizeof(manual)); - write(fd, &manual, sizeof(manual)); - } - - last_pan_cont = *polar_pan_cont; + last_pan_cont = *polar_pan_cont; } /** - * @brief Helper function used to handle incoming messages from the Scorbot ER V serial bus + * @brief Helper function used to handle incoming messages from the Scorbot ER V + * serial bus * @param fd File descriptor for Scorbot ER V serial device -*/ -static void poll_tty_rx(int fd) -{ - static clock_t last_print; - static char buffer[ERV_TTY_BUFFER_LEN]; - static uint16_t len = 0; - - // Handle new info in buffer - char inbox[ERV_TTY_BUFFER_LEN]; - int result = read(fd, &inbox[0], ERV_TTY_BUFFER_LEN); - if (-1 != result) - { - for (uint16_t iter = 0; iter < result; iter++) - { - if (is_term(inbox[iter])) - { - flush_buffer(buffer, len); - memset(buffer, 0, sizeof(buffer)); - len = 0; - last_print = clock(); - continue; - } - - buffer[len++] = inbox[iter]; - } - } - - // Handle rx timeout; If timeout has occurred, flush buffer - double delta_time_ms = (static_cast (clock() - last_print) * 1000) / (CLOCKS_PER_SEC); - if (len > 0 && (float) ERV_RX_TIMEOUT_MS < delta_time_ms) - { + */ +static void poll_tty_rx(int fd) { + static clock_t last_print; + static char buffer[ERV_TTY_BUFFER_LEN]; + static uint16_t len = 0; + + // Handle new info in buffer + char inbox[ERV_TTY_BUFFER_LEN]; + int result = read(fd, &inbox[0], ERV_TTY_BUFFER_LEN); + if (-1 != result) { + for (uint16_t iter = 0; iter < result; iter++) { + if (is_term(inbox[iter])) { flush_buffer(buffer, len); memset(buffer, 0, sizeof(buffer)); len = 0; last_print = clock(); + continue; + } + + buffer[len++] = inbox[iter]; } + } + + // Handle rx timeout; If timeout has occurred, flush buffer + double delta_time_ms = + (static_cast(clock() - last_print) * 1000) / (CLOCKS_PER_SEC); + if (len > 0 && (float)ERV_RX_TIMEOUT_MS < delta_time_ms) { + flush_buffer(buffer, len); + memset(buffer, 0, sizeof(buffer)); + len = 0; + last_print = clock(); + } } -static void execute_acl_cmd(int fd, ACL_Command* command) -{ - write(fd, &command->payload[0], command->len); - LOG_VERBOSE(4, "Sending Command: %s", &command->payload[0]); - LOG_VERBOSE(4, "Delay_ms: %u", command->delay_ms); - ACL_Command_init(command); +static void execute_acl_cmd(int fd, ACL_Command *command) { + write(fd, &command->payload[0], command->len); + LOG_VERBOSE(4, "Sending Command: %s", &command->payload[0]); + LOG_VERBOSE(4, "Delay_ms: %u", command->delay_ms); + ACL_Command_init(command); } /** * @brief Helper function used to asynchronously execute ACL Commands * @param fd File descriptor to write commands to * @param cmd_buffer List of commands to execute -*/ -static void poll_cmd_buffer(int fd, S_List* cmd_buffer) -{ - static bool init = false; - static uint16_t last_delay_ms = 0; - static struct timeval last_cmd_ts; - - if (0 == cmd_buffer->len) return; - if(!init) - { - gettimeofday(&last_cmd_ts, NULL); - init = true; - } + */ +static void poll_cmd_buffer(int fd, S_List *cmd_buffer) { + static bool init = false; + static uint16_t last_delay_ms = 0; + static struct timeval last_cmd_ts; + + if (0 == cmd_buffer->len) return; + if (!init) { + gettimeofday(&last_cmd_ts, NULL); + init = true; + } - struct timeval now; - gettimeofday(&now, NULL); + struct timeval now; + gettimeofday(&now, NULL); - // Check if enough time has elapsed to overcome the delay - uint16_t elapsed_ms = tval_diff_ms(&now, &last_cmd_ts); - if (elapsed_ms < last_delay_ms) - { - // Wait longer - LOG_VERBOSE(6, "elapsed_ms: %u", elapsed_ms); - return; - } + // Check if enough time has elapsed to overcome the delay + uint16_t elapsed_ms = tval_diff_ms(&now, &last_cmd_ts); + if (elapsed_ms < last_delay_ms) { + // Wait longer + LOG_VERBOSE(6, "elapsed_ms: %u", elapsed_ms); + return; + } - // Execute next command - S_List_Node* node = DATA_S_List_pop(cmd_buffer); - if(!node) STD_FAIL_VOID; + // Execute next command + S_List_Node *node = DATA_S_List_pop(cmd_buffer); + if (!node) STD_FAIL_VOID; - ACL_Command *cmd = DATA_LIST_GET_OBJ(node, ACL_Command, node); - last_delay_ms = cmd->delay_ms; - gettimeofday(&last_cmd_ts, NULL); - execute_acl_cmd(fd, cmd); + ACL_Command *cmd = DATA_LIST_GET_OBJ(node, ACL_Command, node); + last_delay_ms = cmd->delay_ms; + gettimeofday(&last_cmd_ts, NULL); + execute_acl_cmd(fd, cmd); - return; + return; } -void Scorbot::Poll() -{ - if (-1 == fd) return; +void Scorbot::Poll() { + if (-1 == fd) return; - poll_polar_pan(fd, &polar_pan_cont, &last_start, &manual_mode); - poll_tty_rx(fd); - poll_cmd_buffer(fd, &cmd_buffer); + poll_polar_pan(fd, &polar_pan_cont, &last_start, &manual_mode); + poll_tty_rx(fd); + poll_cmd_buffer(fd, &cmd_buffer); } -int Scorbot::HandShake() -{ - LOG_INFO("Scorbot Recevied Handshake Command"); - return 0; +int Scorbot::HandShake() { + LOG_INFO("Scorbot Recevied Handshake Command"); + return 0; } -int Scorbot::PolarPan(API_Data_Polar_Pan *pan) -{ - uint8_t iter = 0; - char text[255]; - - S_List cmd_list; - DATA_S_List_init(&cmd_list); - - switch(oversteer) - { - case OVERSTEER_NONE: - ACL_convert_polar_pan_direct(&cmd_list, pan); - break; - case OVERSTEER_IGNORE: - ACL_convert_polar_pan_ignore(&cmd_list, pan); - break; - case OVERSTEER_ABORT: - ACL_convert_polar_pan_abort(&cmd_list, pan); - break; - default: - STD_FAIL; - } +int Scorbot::PolarPan(API_Data_Polar_Pan *pan) { + uint8_t iter = 0; + char text[255]; + + S_List cmd_list; + DATA_S_List_init(&cmd_list); + + switch (oversteer) { + case OVERSTEER_NONE: + ACL_convert_polar_pan_direct(&cmd_list, pan); + break; + case OVERSTEER_IGNORE: + ACL_convert_polar_pan_ignore(&cmd_list, pan); + break; + case OVERSTEER_ABORT: + ACL_convert_polar_pan_abort(&cmd_list, pan); + break; + default: + STD_FAIL; + } + + WriteCommandQueue(&cmd_list); + + iter += sprintf(&text[iter], "Polar Pan Payload:\n"); + iter += sprintf(&text[iter], "\tΔ Azimuth: \t\t%d\n", pan->delta_azimuth); + iter += sprintf(&text[iter], "\tΔ Altitude: \t%d\n", pan->delta_altitude); + iter += sprintf(&text[iter], "\tDelay: \t\t%d\n", pan->delay_ms); + iter += sprintf(&text[iter], "\tTime: \t\t%d\n", pan->time_ms); + LOG_VERBOSE(4, "%s", text); + + return 0; +} - WriteCommandQueue(&cmd_list); +int Scorbot::PolarPanStart(API_Data_Polar_Pan_Start *pan) { + uint8_t iter = 0; + char text[255]; - iter += sprintf(&text[iter], "Polar Pan Payload:\n"); - iter += sprintf(&text[iter], "\tΔ Azimuth: \t\t%d\n", pan->delta_azimuth); - iter += sprintf(&text[iter], "\tΔ Altitude: \t%d\n", pan->delta_altitude); - iter += sprintf(&text[iter], "\tDelay: \t\t%d\n", pan->delay_ms); - iter += sprintf(&text[iter], "\tTime: \t\t%d\n", pan->time_ms); - LOG_VERBOSE(4, "%s", text); + iter += sprintf(&text[iter], "Polar Pan Start Payload:\n"); + iter += sprintf(&text[iter], "\tΔ Azimuth: \t%d\n", pan->delta_azimuth); + iter += sprintf(&text[iter], "\tΔ Altitude: \t%d\n", pan->delta_altitude); + LOG_VERBOSE(4, "%s", text); - return 0; -} + polar_pan_cont = ACL_get_polar_pan_continuous_vector(pan); + gettimeofday(&last_start, NULL); -int Scorbot::PolarPanStart(API_Data_Polar_Pan_Start *pan) -{ - uint8_t iter = 0; - char text[255]; + if ('\0' == polar_pan_cont) PolarPanStop(); + return 0; +} - iter += sprintf(&text[iter], "Polar Pan Start Payload:\n"); - iter += sprintf(&text[iter], "\tΔ Azimuth: \t%d\n", pan->delta_azimuth); - iter += sprintf(&text[iter], "\tΔ Altitude: \t%d\n", pan->delta_altitude); - LOG_VERBOSE(4, "%s", text); +int Scorbot::PolarPanStop() { + polar_pan_cont = '\0'; - polar_pan_cont = ACL_get_polar_pan_continuous_vector(pan); - gettimeofday(&last_start, NULL); + S_List cmd_list; + DATA_S_List_init(&cmd_list); + ACL_enqueue_delay(&cmd_list, 500); + ACL_enqueue_here_cmd(&cmd_list); + WriteCommandQueue(&cmd_list); - if('\0' == polar_pan_cont) PolarPanStop(); - return 0; + return 0; } -int Scorbot::PolarPanStop() -{ - polar_pan_cont = '\0'; +int Scorbot::Home(API_Data_Home *home) { + uint8_t iter = 0; + char text[255]; - S_List cmd_list; - DATA_S_List_init(&cmd_list); - ACL_enqueue_delay(&cmd_list, 500); - ACL_enqueue_here_cmd(&cmd_list); - WriteCommandQueue(&cmd_list); + iter += sprintf(&text[iter], "Home Payload:\n"); + iter += sprintf(&text[iter], "\tDelay: \t\t%d", home->delay_ms); - return 0; + LOG_VERBOSE(4, "%s", text); + + S_List cmd_list; + DATA_S_List_init(&cmd_list); + ACL_home_sequence(&cmd_list); + + WriteCommandQueue(&cmd_list); + + return 0; } -int Scorbot::Home(API_Data_Home* home) -{ - uint8_t iter = 0; - char text[255]; +int Scorbot::SetSpeed(API_Data_Set_Speed *speed) { + uint8_t iter = 0; + char text[255]; - iter += sprintf(&text[iter], "Home Payload:\n"); - iter += sprintf(&text[iter], "\tDelay: \t\t%d", home->delay_ms); + iter += sprintf(&text[iter], "Set Speed Payload:\n"); + iter += sprintf(&text[iter], "\tSpeed: \t\t%d", speed->speed); - LOG_VERBOSE(4, "%s", text); + LOG_VERBOSE(4, "%s", text); - S_List cmd_list; - DATA_S_List_init(&cmd_list); - ACL_home_sequence(&cmd_list); + S_List cmd_list; + DATA_S_List_init(&cmd_list); + ACL_set_speed(&cmd_list, speed); - WriteCommandQueue(&cmd_list); + WriteCommandQueue(&cmd_list); - return 0; + return 0; } -int Scorbot::WriteCommandQueue(S_List* cmd_list) -{ - if (!cmd_list) STD_FAIL; - if (-1 == fd) STD_FAIL; +int Scorbot::WriteCommandQueue(S_List *cmd_list) { + if (!cmd_list) STD_FAIL; + if (-1 == fd) STD_FAIL; - polar_pan_cont = '\0'; - DATA_S_List_append_list(&cmd_buffer, cmd_list); + polar_pan_cont = '\0'; + DATA_S_List_append_list(&cmd_buffer, cmd_list); - return 0; -} \ No newline at end of file + return 0; +} diff --git a/src/ER_V/erv_arm/erv.h b/src/ER_V/erv_arm/erv.h index 8a8b164..f39d2c9 100644 --- a/src/ER_V/erv_arm/erv.h +++ b/src/ER_V/erv_arm/erv.h @@ -1,32 +1,31 @@ #pragma once -#include "arm/arm.h" #include "acl/acl.h" +#include "arm/arm.h" #define ERV_RX_TIMEOUT_MS 500 #define ERV_CONT_POLAR_PAN_TIMEOUT_MS 500 -class Scorbot : public Arm -{ - public: - - Scorbot(const char* dev); - ~Scorbot(); +class Scorbot : public Arm { + public: + Scorbot(const char *dev); + ~Scorbot(); - private: - char dev[32]; - int fd; - char polar_pan_cont; - bool manual_mode; - OversteerConfig oversteer; - S_List cmd_buffer; - struct timeval last_start; + private: + char dev[32]; + int fd; + char polar_pan_cont; + bool manual_mode; + OversteerConfig oversteer; + S_List cmd_buffer; + struct timeval last_start; - int HandShake(); - int PolarPan(API_Data_Polar_Pan *pan); - int PolarPanStart(API_Data_Polar_Pan_Start *pan); - int PolarPanStop(); - int Home(API_Data_Home *home); - int WriteCommandQueue(S_List *cmd_list); - void Poll(); -}; \ No newline at end of file + int HandShake(); + int PolarPan(API_Data_Polar_Pan *pan); + int PolarPanStart(API_Data_Polar_Pan_Start *pan); + int PolarPanStop(); + int Home(API_Data_Home *home); + int SetSpeed(API_Data_Set_Speed *speed); + int WriteCommandQueue(S_List *cmd_list); + void Poll(); +}; diff --git a/src/ER_V/erv_conf/erv_conf.cpp b/src/ER_V/erv_conf/erv_conf.cpp index 5b05c3f..c19ff31 100644 --- a/src/ER_V/erv_conf/erv_conf.cpp +++ b/src/ER_V/erv_conf/erv_conf.cpp @@ -1,29 +1,22 @@ +#include "erv_conf/erv_conf.h" + #include -#include "erv_conf/erv_conf.h" #include "conf/config.h" #include "util/comm.h" -#define LOG_CONSOLE_THRESHOLD_THIS LOG_THRESHOLD_DEFAULT -#define LOG_FILE_THRESHOLD_THIS LOG_THRESHOLD_DEFAULT +#define LOG_CONSOLE_THRESHOLD_THIS LOG_THRESHOLD_DEFAULT +#define LOG_FILE_THRESHOLD_THIS LOG_THRESHOLD_DEFAULT -ERVConfig::ERVConfig() -{ - dev_idx = AddKey(ERV_CONF_DEV_KEY, ERV_CONF_DEV_DEFAULT); +ERVConfig::ERVConfig() { + dev_idx = AddKey(ERV_CONF_DEV_KEY, ERV_CONF_DEV_DEFAULT); } -ERVConfig::~ERVConfig() -{ +ERVConfig::~ERVConfig() {} -} - -const char* ERVConfig::GetScorbotDevicePath() -{ - return GetVal(dev_idx); -} +const char *ERVConfig::GetScorbotDevicePath() { return GetVal(dev_idx); } -int ERVConfig::LoadDefaults() -{ - dev_idx = AddKey(ERV_CONF_DEV_KEY, ERV_CONF_DEV_DEFAULT); - return 0; +int ERVConfig::LoadDefaults() { + dev_idx = AddKey(ERV_CONF_DEV_KEY, ERV_CONF_DEV_DEFAULT); + return 0; } \ No newline at end of file diff --git a/src/ER_V/erv_conf/erv_conf.h b/src/ER_V/erv_conf/erv_conf.h index fd78c9f..0b35987 100644 --- a/src/ER_V/erv_conf/erv_conf.h +++ b/src/ER_V/erv_conf/erv_conf.h @@ -6,29 +6,28 @@ #include "log/log_config.h" #include "socket/socket_conf.h" -#define ERV_CONF_DEV_KEY "scorbot_dev" -#define ERV_CONF_DEV_DEFAULT "/dev/ttyUSB0" +#define ERV_CONF_DEV_KEY "scorbot_dev" +#define ERV_CONF_DEV_DEFAULT "/dev/ttyUSB0" -class ERVConfig: public LogConfig, - public SocketConfig -{ - private: - uint8_t dev_idx; +class ERVConfig : public LogConfig, public SocketConfig { + private: + uint8_t dev_idx; - public: - ERVConfig(); - virtual ~ERVConfig(); + public: + ERVConfig(); + virtual ~ERVConfig(); - /** - * @brief Returns a const char pointer containing the linux device path of the Scorbot ER V serial connection - * @returns const char pointer on success, NULL on failure - */ - const char* GetScorbotDevicePath(); + /** + * @brief Returns a const char pointer containing the linux device path of the + * Scorbot ER V serial connection + * @returns const char pointer on success, NULL on failure + */ + const char *GetScorbotDevicePath(); - /** - * @brief Loads the ER V default configuration - * @details Clear Key-Val table before using LoadDefaults - * @returns 0 on success, -1 on failure - */ - int LoadDefaults(); + /** + * @brief Loads the ER V default configuration + * @details Clear Key-Val table before using LoadDefaults + * @returns 0 on success, -1 on failure + */ + int LoadDefaults(); }; \ No newline at end of file diff --git a/src/ER_V/log_demo.c b/src/ER_V/log_demo.c index 960b59e..4f8efbd 100644 --- a/src/ER_V/log_demo.c +++ b/src/ER_V/log_demo.c @@ -1,23 +1,22 @@ #include "log/log.h" -#define LOG_FILE_THRESHOLD_THIS LOG_THRESHOLD_MAX -#define LOG_CONSOLE_THRESHOLD_THIS LOG_THRESHOLD_DEFAULT +#define LOG_FILE_THRESHOLD_THIS LOG_THRESHOLD_MAX +#define LOG_CONSOLE_THRESHOLD_THIS LOG_THRESHOLD_DEFAULT -int main() -{ - LOG_init(); - LOG_start(); +int main() { + LOG_init(); + LOG_start(); - LOG_FATAL("Fatal error"); - LOG_ERROR("Standard error"); - LOG_IEC(); - LOG_WARN("Warning"); - LOG_INFO("Information"); - LOG_VERBOSE(0, "A little extra info"); - LOG_VERBOSE(1, "Debugging"); - LOG_VERBOSE(2, "A lot of debugging"); - LOG_VERBOSE(9, "Dear god, the debugging"); + LOG_FATAL("Fatal error"); + LOG_ERROR("Standard error"); + LOG_IEC(); + LOG_WARN("Warning"); + LOG_INFO("Information"); + LOG_VERBOSE(0, "A little extra info"); + LOG_VERBOSE(1, "Debugging"); + LOG_VERBOSE(2, "A lot of debugging"); + LOG_VERBOSE(9, "Dear god, the debugging"); - LOG_stop(); - LOG_destory(); + LOG_stop(); + LOG_destory(); } \ No newline at end of file diff --git a/src/ER_V/main.cpp b/src/ER_V/main.cpp index 729d094..b5aaa02 100644 --- a/src/ER_V/main.cpp +++ b/src/ER_V/main.cpp @@ -1,126 +1,121 @@ +#include +#include +#include #include #include -#include #include -#include -#include -#include "util/comm.h" -#include "util/array.h" -#include "log/log.h" -#include "sub/sub.h" -#include "socket/socket.h" +#include "api/api.h" #include "arm/arm.h" -#include "erv_arm/erv.h" #include "conf/config.h" +#include "erv_arm/erv.h" #include "erv_conf/erv_conf.h" +#include "log/log.h" +#include "socket/socket.h" +#include "sub/sub.h" +#include "util/array.h" +#include "util/comm.h" -#include "api/api.h" - -#define LOG_FILE_THRESHOLD_THIS LOG_THRESHOLD_MAX -#define LOG_CONSOLE_THRESHOLD_THIS LOG_THRESHOLD_MAX +#define LOG_FILE_THRESHOLD_THIS LOG_THRESHOLD_MAX +#define LOG_CONSOLE_THRESHOLD_THIS LOG_THRESHOLD_MAX -const char* app_name; +const char *app_name; volatile int quit_sig = 0; -static void quit_handler(int signum) -{ - quit_sig = signum; // quit control loop +static void quit_handler(int signum) { + quit_sig = signum; // quit control loop } -static int register_intr() -{ - struct sigaction sa; - sa.sa_handler = quit_handler; - sigemptyset(&sa.sa_mask); - sa.sa_flags = SA_RESTART; /* Restart functions if - interrupted by handler */ - - if (sigaction(SIGINT, &sa, NULL) == -1) return -1; - if (sigaction(SIGQUIT, &sa, NULL) == -1) return -1; - if (sigaction(SIGABRT, &sa, NULL) == -1) return -1; - return 0; +static int register_intr() { + struct sigaction sa; + sa.sa_handler = quit_handler; + sigemptyset(&sa.sa_mask); + sa.sa_flags = SA_RESTART; /* Restart functions if + interrupted by handler */ + + if (sigaction(SIGINT, &sa, NULL) == -1) return -1; + if (sigaction(SIGQUIT, &sa, NULL) == -1) return -1; + if (sigaction(SIGABRT, &sa, NULL) == -1) return -1; + return 0; } #if VALGRIND -static void dummy_msg(Subscriber* hermes) -{ - SUB_Buffer* buf = hermes->DequeueBuffer(SUB_QUEUE_FREE); - if (!buf) return; +static void dummy_msg(Subscriber *hermes) { + SUB_Buffer *buf = hermes->DequeueBuffer(SUB_QUEUE_FREE); + if (!buf) return; - API_Data_Wrapper* msg = (API_Data_Wrapper*) &buf->body[0]; + API_Data_Wrapper *msg = (API_Data_Wrapper *)&buf->body[0]; - msg->header.cmd_id = htobe32(0x0); - msg->header.reserved_1 = htobe16(0); - msg->header.cmd_val = htobe16(API_CMD_HOME); - msg->header.len = htobe16(sizeof(API_Data_Home)); + msg->header.cmd_id = htobe32(0x0); + msg->header.reserved_1 = htobe16(0); + msg->header.cmd_val = htobe16(API_CMD_HOME); + msg->header.len = htobe16(sizeof(API_Data_Home)); - API_Data_Home* cmd = (API_Data_Home*) &msg->payload_head; + API_Data_Home *cmd = (API_Data_Home *)&msg->payload_head; - cmd->delay_ms = 0; + cmd->delay_ms = 0; - buf->len = sizeof(API_Data_Home) + sizeof(API_Data_Header) + 2; - hermes->EnqueueBuffer(SUB_QUEUE_COMMAND, buf); + buf->len = sizeof(API_Data_Home) + sizeof(API_Data_Header) + 2; + hermes->EnqueueBuffer(SUB_QUEUE_COMMAND, buf); } #endif -int main(int argc, char* argv[]) -{ - LOG_prep(); - app_name = argv[0]; - register_intr(); +int main(int argc, char *argv[]) { + LOG_prep(); + app_name = argv[0]; + register_intr(); - // Initalize program; Setup Logging - ERVConfig conf = ERVConfig(); + // Initalize program; Setup Logging + ERVConfig conf = ERVConfig(); - // Setup config priority - const char* conf_loc[] = {NULL, CONF_DEFAULT_LOCATION}; - uint8_t conf_loc_len = UTIL_len(conf_loc); - if (argc > 1) conf_loc[0] = argv[1]; + // Setup config priority + const char *conf_loc[] = {NULL, CONF_DEFAULT_LOCATION}; + uint8_t conf_loc_len = UTIL_len(conf_loc); + if (argc > 1) conf_loc[0] = argv[1]; - for (uint8_t iter = 0; iter < conf_loc_len; iter++) - if(conf_loc[iter] && !conf.SetFilePath(conf_loc[iter])) - break; // If file is successfully set, break loop + for (uint8_t iter = 0; iter < conf_loc_len; iter++) + if (conf_loc[iter] && !conf.SetFilePath(conf_loc[iter])) + break; // If file is successfully set, break loop - conf.ParseConfig(); + conf.ParseConfig(); - LOG_init(conf.GetLogLocation()); - LOG_start(); + LOG_init(conf.GetLogLocation()); + LOG_start(); - conf.DumpToLog(LOG_INFO); + conf.DumpToLog(LOG_INFO); - // Init Modules - Subscriber hermes = Subscriber(); - Inbox* inbox = new Socket(); + // Init Modules + Subscriber hermes = Subscriber(); + Inbox *inbox = new Socket(); - Arm* bot = new Scorbot(conf.GetScorbotDevicePath()); + Arm *bot = new Scorbot(conf.GetScorbotDevicePath()); - // Register modules - inbox->RegisterSubscriber(&hermes); - bot->RegisterSubscriber(&hermes); + // Register modules + inbox->RegisterSubscriber(&hermes); + bot->RegisterSubscriber(&hermes); - // Start - hermes.Start(); - if(-1 == bot->Start()) quit_handler(SIGABRT); - inbox->Start(); + // Start + hermes.Start(); + if (-1 == bot->Start()) quit_handler(SIGABRT); + inbox->Start(); - // Loop - if (!quit_sig) LOG_INFO("Ready."); - while(!quit_sig); - LOG_VERBOSE(0, "Quit signal: %d", quit_sig); - LOG_INFO("Shutting down..."); + // Loop + if (!quit_sig) LOG_INFO("Ready."); + while (!quit_sig); + LOG_VERBOSE(0, "Quit signal: %d", quit_sig); + LOG_INFO("Shutting down..."); - // Cleanup running processes - inbox->Stop(); - hermes.Stop(); - bot->Stop(); + // Cleanup running processes + inbox->Stop(); + hermes.Stop(); + bot->Stop(); - // Release resources - delete bot; - delete inbox; + // Release resources + delete bot; + delete inbox; - // End demo - LOG_INFO("End Program."); - LOG_stop(); - LOG_destory(); + // End demo + LOG_INFO("End Program."); + LOG_stop(); + LOG_destory(); } \ No newline at end of file diff --git a/src/Ichor/all_tests.cpp b/src/Ichor/all_tests.cpp index af3b808..6fe93ab 100644 --- a/src/Ichor/all_tests.cpp +++ b/src/Ichor/all_tests.cpp @@ -1,12 +1,8 @@ #include #include -TEST_GROUP(Group) {}; +TEST_GROUP(Group){}; -IGNORE_TEST(Group, Test) { -}; +IGNORE_TEST(Group, Test){}; -int main(int argc, char ** argv) -{ - RUN_ALL_TESTS(argc, argv); -} \ No newline at end of file +int main(int argc, char **argv) { RUN_ALL_TESTS(argc, argv); } \ No newline at end of file diff --git a/src/Ichor/arm/ichor_arm.cpp b/src/Ichor/arm/ichor_arm.cpp index 2b51a54..eb7b698 100644 --- a/src/Ichor/arm/ichor_arm.cpp +++ b/src/Ichor/arm/ichor_arm.cpp @@ -1,165 +1,147 @@ -#include -#include -#include -#include +#include "arm/ichor_arm.h" + #include #include +#include +#include #include +#include +#include #include #include -#include - -#include "arm/ichor_arm.h" -#include "motor/motor.h" +#include #include "log/log.h" +#include "motor/motor.h" - -#define LOG_CONSOLE_THRESHOLD_THIS LOG_THRESHOLD_DEFAULT -#define LOG_FILE_THRESHOLD_THIS LOG_THRESHOLD_MAX +#define LOG_CONSOLE_THRESHOLD_THIS LOG_THRESHOLD_DEFAULT +#define LOG_FILE_THRESHOLD_THIS LOG_THRESHOLD_MAX #define ERV_CLOCK CLOCK_REALTIME -static float dead_vel (int32_t target, int32_t start, int32_t pos) -{ - return 0; -} +static float dead_vel(int32_t target, int32_t start, int32_t pos) { return 0; } -static float open_loop_vel (int32_t target, int32_t start, int32_t pos) -{ - if (target == 0) return 0; - return target > 0 ? 1 : -1; +static float open_loop_vel(int32_t target, int32_t start, int32_t pos) { + if (target == 0) return 0; + return target > 0 ? 1 : -1; } -static void set_velocity(Driver** axis, float (*vel)(int32_t target, int32_t start, int32_t pos)) -{ - for (uint8_t idx = 0; idx < ICHOR_AXIS_COUNT; idx++) - { - if (axis[idx]) axis[idx]->SetVelocityFunc(vel); - } +static void set_velocity(Driver **axis, + float (*vel)(int32_t target, int32_t start, + int32_t pos)) { + for (uint8_t idx = 0; idx < ICHOR_AXIS_COUNT; idx++) { + if (axis[idx]) axis[idx]->SetVelocityFunc(vel); + } } -Ichor::Ichor(const char* isr_dev, const char* i2c_dev, uint8_t dac0_addr, uint8_t dac1_addr, uint8_t adc_addr) -{ - int i2c_fd = open(i2c_dev, O_RDWR); - if (i2c_fd < 0) LOG_WARN("Failed to open I2C bus"); - else LOG_INFO("Successfully opened I2C bus"); +Ichor::Ichor(const char *isr_dev, const char *i2c_dev, uint8_t dac0_addr, + uint8_t dac1_addr, uint8_t adc_addr) { + int i2c_fd = open(i2c_dev, O_RDWR); + if (i2c_fd < 0) + LOG_WARN("Failed to open I2C bus"); + else + LOG_INFO("Successfully opened I2C bus"); - isr = new IchorISR(isr_dev); + isr = new IchorISR(isr_dev); - dac[0] = new PCA9685PW(i2c_fd, dac0_addr); - // dac[1] = new PCA9685PW(i2c_fd, dac1_addr); - // TODO: Add adc + dac[0] = new PCA9685PW(i2c_fd, dac0_addr); + // dac[1] = new PCA9685PW(i2c_fd, dac1_addr); + // TODO: Add adc - for (uint8_t idx = 0; idx < ICHOR_AXIS_COUNT; idx++) - axis[idx] = NULL; + for (uint8_t idx = 0; idx < ICHOR_AXIS_COUNT; idx++) axis[idx] = NULL; } -Ichor::~Ichor() -{ - // dac[0].ResetDevice(); // Resets all PCA9685PW devices on bus +Ichor::~Ichor() { + // dac[0].ResetDevice(); // Resets all PCA9685PW devices on bus } -int Ichor::RegisterMotor( uint8_t motor_index, - uint8_t dac_index, uint8_t dac_in1, uint8_t dac_in2, uint8_t dac_speed, - uint8_t enc_a, uint8_t enc_b, uint8_t adc_channel ) -{ - if (motor_index > 8 || dac_index > 1) STD_FAIL; - axis[motor_index] = new Driver(dac[dac_index], dac_in1, dac_in2, dac_speed, isr, enc_a, enc_b, NULL, adc_channel); - axis[motor_index]->SetSpeedCoefficient(50); - axis[motor_index]->SetVelocityFunc(&dead_vel); - return 0; +int Ichor::RegisterMotor(uint8_t motor_index, uint8_t dac_index, + uint8_t dac_in1, uint8_t dac_in2, uint8_t dac_speed, + uint8_t enc_a, uint8_t enc_b, uint8_t adc_channel) { + if (motor_index > 8 || dac_index > 1) STD_FAIL; + axis[motor_index] = new Driver(dac[dac_index], dac_in1, dac_in2, dac_speed, + isr, enc_a, enc_b, NULL, adc_channel); + axis[motor_index]->SetSpeedCoefficient(50); + axis[motor_index]->SetVelocityFunc(&dead_vel); + return 0; } -int Ichor::Init() -{ - isr->AllocatePins(); - return 0; +int Ichor::Init() { + isr->AllocatePins(); + return 0; } -void Ichor::Poll() -{ - isr->ProcessEvents(); // Check GPIO interrupts (could be an abort signal) - // TODO // Check ADC values (overcurrent / overexertion) - for (uint8_t idx = 0; idx < ICHOR_AXIS_COUNT; idx++) - { - if (!axis[idx]) continue; - axis[idx]->Poll(); // Update motors with new control information - } - - dac[0]->FlushQueues(); // Flush pending DAC writes - usleep(25e3); // 25 ms delay (defacto delay in Talos Operator so far) -} +void Ichor::Poll() { + isr->ProcessEvents(); // Check GPIO interrupts (could be an abort signal) + // TODO // Check ADC values (overcurrent / overexertion) + for (uint8_t idx = 0; idx < ICHOR_AXIS_COUNT; idx++) { + if (!axis[idx]) continue; + axis[idx]->Poll(); // Update motors with new control information + } -int Ichor::HandShake() -{ - return 0; + dac[0]->FlushQueues(); // Flush pending DAC writes + usleep(25e3); // 25 ms delay (defacto delay in Talos Operator so far) } -int Ichor::PolarPan(API_Data_Polar_Pan *pan) -{ - - switch(oversteer) - { - case OVERSTEER_NONE: - break; - case OVERSTEER_IGNORE: - break; - case OVERSTEER_ABORT: - break; - default: - STD_FAIL; - } - - - uint8_t iter = 0; - char text[255]; - - iter += sprintf(&text[iter], "Polar Pan Payload:\n"); - iter += sprintf(&text[iter], "\tΔ Azimuth: \t%d\n", pan->delta_azimuth); - iter += sprintf(&text[iter], "\tΔ Altitude: \t%d\n", pan->delta_altitude); - iter += sprintf(&text[iter], "\tDelay: \t\t%d\n", pan->delay_ms); - iter += sprintf(&text[iter], "\tTime: \t\t%d\n", pan->time_ms); - LOG_VERBOSE(4, "%s", text); - - return 0; +int Ichor::HandShake() { return 0; } + +int Ichor::PolarPan(API_Data_Polar_Pan *pan) { + switch (oversteer) { + case OVERSTEER_NONE: + break; + case OVERSTEER_IGNORE: + break; + case OVERSTEER_ABORT: + break; + default: + STD_FAIL; + } + + uint8_t iter = 0; + char text[255]; + + iter += sprintf(&text[iter], "Polar Pan Payload:\n"); + iter += sprintf(&text[iter], "\tΔ Azimuth: \t%d\n", pan->delta_azimuth); + iter += sprintf(&text[iter], "\tΔ Altitude: \t%d\n", pan->delta_altitude); + iter += sprintf(&text[iter], "\tDelay: \t\t%d\n", pan->delay_ms); + iter += sprintf(&text[iter], "\tTime: \t\t%d\n", pan->time_ms); + LOG_VERBOSE(4, "%s", text); + + return 0; } -int Ichor::PolarPanStart(API_Data_Polar_Pan_Start *pan) -{ - uint8_t iter = 0; - char text[255]; +int Ichor::PolarPanStart(API_Data_Polar_Pan_Start *pan) { + uint8_t iter = 0; + char text[255]; - if (!axis[0] || !axis[2]) STD_FAIL; + if (!axis[0] || !axis[2]) STD_FAIL; - axis[0]->SetVelocityFunc(&open_loop_vel); - axis[0]->SetTarget(pan->delta_azimuth, 0); + axis[0]->SetVelocityFunc(&open_loop_vel); + axis[0]->SetTarget(pan->delta_azimuth, 0); - axis[2]->SetVelocityFunc(&open_loop_vel); - axis[2]->SetTarget(pan->delta_altitude, 0); + axis[2]->SetVelocityFunc(&open_loop_vel); + axis[2]->SetTarget(pan->delta_altitude, 0); - iter += sprintf(&text[iter], "Polar Pan Start Payload:\n"); - iter += sprintf(&text[iter], "\tΔ Azimuth: \t%d\n", pan->delta_azimuth); - iter += sprintf(&text[iter], "\tΔ Altitude: \t%d\n", pan->delta_altitude); - LOG_VERBOSE(4, "%s", text); + iter += sprintf(&text[iter], "Polar Pan Start Payload:\n"); + iter += sprintf(&text[iter], "\tΔ Azimuth: \t%d\n", pan->delta_azimuth); + iter += sprintf(&text[iter], "\tΔ Altitude: \t%d\n", pan->delta_altitude); + LOG_VERBOSE(4, "%s", text); - return 0; + return 0; } -int Ichor::PolarPanStop() -{ - axis[0]->SetVelocityFunc(&dead_vel); - axis[2]->SetVelocityFunc(&dead_vel); - return 0; +int Ichor::PolarPanStop() { + axis[0]->SetVelocityFunc(&dead_vel); + axis[2]->SetVelocityFunc(&dead_vel); + return 0; } -int Ichor::Home(API_Data_Home* home) -{ - uint8_t iter = 0; - char text[255]; +int Ichor::Home(API_Data_Home *home) { + uint8_t iter = 0; + char text[255]; - iter += sprintf(&text[iter], "Home Payload:\n"); - iter += sprintf(&text[iter], "\tDelay: \t\t%d", home->delay_ms); + iter += sprintf(&text[iter], "Home Payload:\n"); + iter += sprintf(&text[iter], "\tDelay: \t\t%d", home->delay_ms); - return 0; + return 0; } \ No newline at end of file diff --git a/src/Ichor/arm/ichor_arm.h b/src/Ichor/arm/ichor_arm.h index cff462e..023fba5 100644 --- a/src/Ichor/arm/ichor_arm.h +++ b/src/Ichor/arm/ichor_arm.h @@ -1,38 +1,38 @@ #pragma once #include "arm/arm.h" +#include "dac/PCA9685PW.h" #include "driver/driver.h" #include "gpio/isr.h" -#include "dac/PCA9685PW.h" #define ICHOR_AXIS_COUNT 8 -class Ichor : public Arm -{ - public: - Ichor(const char* isr_dev, const char* i2c_dev, uint8_t dac0_addr, uint8_t dac1_addr, uint8_t adc_addr); - ~Ichor(); - - int RegisterMotor(uint8_t motor_index, - uint8_t dac_index, uint8_t dac_in1, uint8_t dac_in2, uint8_t dac_speed, - uint8_t enc_a, uint8_t enc_b, uint8_t adc_channel); - - int Init(); - - private: - int i2c_fd; - Driver* axis[ICHOR_AXIS_COUNT]; - PCA9685PW* dac[2]; - IchorISR* isr; - - char polar_pan_cont; - bool manual_mode; - OversteerConfig oversteer; - - int HandShake(); - int PolarPan(API_Data_Polar_Pan *pan); - int PolarPanStart(API_Data_Polar_Pan_Start *pan); - int PolarPanStop(); - int Home(API_Data_Home *home); - void Poll(); +class Ichor : public Arm { + public: + Ichor(const char *isr_dev, const char *i2c_dev, uint8_t dac0_addr, + uint8_t dac1_addr, uint8_t adc_addr); + ~Ichor(); + + int RegisterMotor(uint8_t motor_index, uint8_t dac_index, uint8_t dac_in1, + uint8_t dac_in2, uint8_t dac_speed, uint8_t enc_a, + uint8_t enc_b, uint8_t adc_channel); + + int Init(); + + private: + int i2c_fd; + Driver *axis[ICHOR_AXIS_COUNT]; + PCA9685PW *dac[2]; + IchorISR *isr; + + char polar_pan_cont; + bool manual_mode; + OversteerConfig oversteer; + + int HandShake(); + int PolarPan(API_Data_Polar_Pan *pan); + int PolarPanStart(API_Data_Polar_Pan_Start *pan); + int PolarPanStop(); + int Home(API_Data_Home *home); + void Poll(); }; \ No newline at end of file diff --git a/src/Ichor/conf/ichor_conf.cpp b/src/Ichor/conf/ichor_conf.cpp index a9e5c05..ad87c1c 100644 --- a/src/Ichor/conf/ichor_conf.cpp +++ b/src/Ichor/conf/ichor_conf.cpp @@ -1,28 +1,19 @@ +#include "conf/ichor_conf.h" + #include -#include "conf/ichor_conf.h" #include "conf/config.h" #include "util/comm.h" -#define LOG_CONSOLE_THRESHOLD_THIS LOG_THRESHOLD_DEFAULT -#define LOG_FILE_THRESHOLD_THIS LOG_THRESHOLD_DEFAULT +#define LOG_CONSOLE_THRESHOLD_THIS LOG_THRESHOLD_DEFAULT +#define LOG_FILE_THRESHOLD_THIS LOG_THRESHOLD_DEFAULT -IchorConfig::IchorConfig() -{ - AddKey(ICHOR_CONF_I2C_DEV_KEY, ICHOR_CONF_I2C_DEV_DEFAULT); +IchorConfig::IchorConfig() { + AddKey(ICHOR_CONF_I2C_DEV_KEY, ICHOR_CONF_I2C_DEV_DEFAULT); } -IchorConfig::~IchorConfig() -{ +IchorConfig::~IchorConfig() {} -} - -const char* IchorConfig::GetI2CDev() -{ - return GetVal(ICHOR_CONF_I2C_DEV_KEY); -} +const char *IchorConfig::GetI2CDev() { return GetVal(ICHOR_CONF_I2C_DEV_KEY); } -int IchorConfig::LoadDefaults() -{ - return 0; -} \ No newline at end of file +int IchorConfig::LoadDefaults() { return 0; } \ No newline at end of file diff --git a/src/Ichor/conf/ichor_conf.h b/src/Ichor/conf/ichor_conf.h index 2bc7680..5d95da8 100644 --- a/src/Ichor/conf/ichor_conf.h +++ b/src/Ichor/conf/ichor_conf.h @@ -6,24 +6,23 @@ #include "log/log_config.h" #include "tamq/tamq_conf.h" -#define ICHOR_CONF_I2C_DEV_KEY "i2c_dev" -#define ICHOR_CONF_I2C_DEV_DEFAULT "/dev/i2c-1" +#define ICHOR_CONF_I2C_DEV_KEY "i2c_dev" +#define ICHOR_CONF_I2C_DEV_DEFAULT "/dev/i2c-1" -class IchorConfig: public LogConfig - // ,public TAMQ_Config +class IchorConfig : public LogConfig +// ,public TAMQ_Config { - private: + private: + public: + IchorConfig(); + virtual ~IchorConfig(); - public: - IchorConfig(); - virtual ~IchorConfig(); + const char *GetI2CDev(); - const char* GetI2CDev(); - - /** - * @brief Loads the ER V default configuration - * @details Clear Key-Val table before using LoadDefaults\ - * @returns 0 on success, -1 on failure - */ - int LoadDefaults(); + /** + * @brief Loads the ER V default configuration + * @details Clear Key-Val table before using LoadDefaults\ + * @returns 0 on success, -1 on failure + */ + int LoadDefaults(); }; \ No newline at end of file diff --git a/src/Ichor/dummy_main.cpp b/src/Ichor/dummy_main.cpp index c0e6c14..2646d0b 100644 --- a/src/Ichor/dummy_main.cpp +++ b/src/Ichor/dummy_main.cpp @@ -1,87 +1,81 @@ -#include +#include +#include +#include +#include +#include #include #include -#include -#include +#include #include -#include -#include #include -#include -#include "util/comm.h" -#include "util/array.h" -#include "log/log.h" +#include "arm/ichor_arm.h" #include "conf/config.h" - +#include "conf/ichor_conf.h" #include "dac/PCA9685PW.h" -#include "gpio/isr.h" #include "driver/driver.h" +#include "gpio/isr.h" +#include "log/log.h" +#include "util/array.h" +#include "util/comm.h" -#include "arm/ichor_arm.h" -#include "conf/ichor_conf.h" - -#define LOG_FILE_THRESHOLD_THIS LOG_THRESHOLD_MAX -#define LOG_CONSOLE_THRESHOLD_THIS LOG_THRESHOLD_MAX +#define LOG_FILE_THRESHOLD_THIS LOG_THRESHOLD_MAX +#define LOG_CONSOLE_THRESHOLD_THIS LOG_THRESHOLD_MAX -#define ENC_A 24 -#define ENC_B 25 -#define DAC_IN1 4 -#define DAC_IN2 3 -#define DAC_SPEED 2 +#define ENC_A 24 +#define ENC_B 25 +#define DAC_IN1 4 +#define DAC_IN2 3 +#define DAC_SPEED 2 #define ADC_CHANNEL -1 -int16_t velocity_square (int32_t target, int32_t pos) -{ - if (target == pos) return 0; - return DAC_PCA_MAX_DUTY_CYCLE * (target - pos > 0 ? 1 : -1); +int16_t velocity_square(int32_t target, int32_t pos) { + if (target == pos) return 0; + return DAC_PCA_MAX_DUTY_CYCLE * (target - pos > 0 ? 1 : -1); } -int16_t velocity_sine (int32_t target, int32_t pos) -{ - struct timeval tv; - gettimeofday(&tv, NULL); +int16_t velocity_sine(int32_t target, int32_t pos) { + struct timeval tv; + gettimeofday(&tv, NULL); - float tmp = ((tv.tv_sec % 10) * 1e6 + tv.tv_usec) / 1e6f; - tmp = sin(tmp * M_PI / 5.f); - tmp *= DAC_PCA_MAX_DUTY_CYCLE; - return (int16_t) tmp; + float tmp = ((tv.tv_sec % 10) * 1e6 + tv.tv_usec) / 1e6f; + tmp = sin(tmp * M_PI / 5.f); + tmp *= DAC_PCA_MAX_DUTY_CYCLE; + return (int16_t)tmp; } -int main(int argc, char* argv[]) -{ - LOG_prep(); - - // Initalize program; Setup Logging - IchorConfig conf = IchorConfig(); +int main(int argc, char *argv[]) { + LOG_prep(); - // Setup config priority - const char* conf_loc[] = {NULL, CONF_DEFAULT_LOCATION}; - uint8_t conf_loc_len = UTIL_len(conf_loc); - if (argc > 1) conf_loc[0] = argv[1]; + // Initalize program; Setup Logging + IchorConfig conf = IchorConfig(); - for (uint8_t iter = 0; iter < conf_loc_len; iter++) - if(conf_loc[iter] && !conf.SetFilePath(conf_loc[iter])) - break; // If file is successfully set, break loop + // Setup config priority + const char *conf_loc[] = {NULL, CONF_DEFAULT_LOCATION}; + uint8_t conf_loc_len = UTIL_len(conf_loc); + if (argc > 1) conf_loc[0] = argv[1]; - conf.ParseConfig(); + for (uint8_t iter = 0; iter < conf_loc_len; iter++) + if (conf_loc[iter] && !conf.SetFilePath(conf_loc[iter])) + break; // If file is successfully set, break loop - LOG_init(conf.GetLogLocation()); - LOG_start(); + conf.ParseConfig(); - conf.DumpToLog(LOG_INFO); + LOG_init(conf.GetLogLocation()); + LOG_start(); - /*************************************************************/ - /************************START SANDBOX************************/ - /*************************************************************/ + conf.DumpToLog(LOG_INFO); - int fd = open(conf.GetI2CDev(), O_RDWR); - if (fd < 0) LOG_WARN("Failed to open I2C bus"); - PCA9685PW dac = PCA9685PW(fd, 0x60); - IchorISR isr = IchorISR(ISR_CHIP_PATH); + /*************************************************************/ + /************************START SANDBOX************************/ + /*************************************************************/ + int fd = open(conf.GetI2CDev(), O_RDWR); + if (fd < 0) LOG_WARN("Failed to open I2C bus"); + PCA9685PW dac = PCA9685PW(fd, 0x60); + IchorISR isr = IchorISR(ISR_CHIP_PATH); - #if 0 +#if 0 dac.SetDutyCycle(DAC_IN1, 0); dac.SetDutyCycle(DAC_IN2, DAC_PCA_MAX_DUTY_CYCLE); dac.SetDutyCycle(DAC_SPEED, DAC_PCA_MAX_DUTY_CYCLE); @@ -109,49 +103,43 @@ int main(int argc, char* argv[]) usleep(10e6); - #else - Driver driver = Driver( &dac, DAC_IN1, DAC_IN2, DAC_SPEED, - &isr, ENC_A, ENC_B, - NULL, ADC_CHANNEL ); +#else + Driver driver = Driver(&dac, DAC_IN1, DAC_IN2, DAC_SPEED, &isr, ENC_A, ENC_B, + NULL, ADC_CHANNEL); - driver.SetVelocityFunc(&velocity_sine); - driver.SetSpeedCoefficient(100); + driver.SetVelocityFunc(&velocity_sine); + driver.SetSpeedCoefficient(100); - isr.AllocatePins(); - dac.InitDevice(); + isr.AllocatePins(); + dac.InitDevice(); + struct timeval start, stop; + bool loc_1 = true; + while (1) { + driver.SetTarget(loc_1 ? 0 : 3000); - struct timeval start, stop; - bool loc_1 = true; - while(1) - { - driver.SetTarget(loc_1 ? 0 : 3000); + gettimeofday(&start, NULL); + while (1) { + isr.ProcessEvents(); // Check GPIO interrupts (could be an abort signal) + // TODO // Check ADC values (overcurrent / overexertion) + driver.Poll(); // Update motors with new control information + dac.FlushQueues(); // Flush pending DAC writes - gettimeofday(&start, NULL); - while(1) - { - isr.ProcessEvents(); // Check GPIO interrupts (could be an abort signal) - // TODO // Check ADC values (overcurrent / overexertion) - driver.Poll(); // Update motors with new control information - dac.FlushQueues(); // Flush pending DAC writes - - gettimeofday(&stop, NULL); - if (stop.tv_sec * 10e6+ stop.tv_usec >= 3e6) break; - usleep(2.5e3); // 25 ms delay (defacto delay in Talos Operator so far) - } - - loc_1 = !loc_1; + gettimeofday(&stop, NULL); + if (stop.tv_sec * 10e6 + stop.tv_usec >= 3e6) break; + usleep(2.5e3); // 25 ms delay (defacto delay in Talos Operator so far) } - #endif - + loc_1 = !loc_1; + } +#endif - /*************************************************************/ - /*************************END SANDBOX*************************/ - /*************************************************************/ + /*************************************************************/ + /*************************END SANDBOX*************************/ + /*************************************************************/ - // End demo - LOG_INFO("End Program."); - LOG_stop(); - LOG_destory(); + // End demo + LOG_INFO("End Program."); + LOG_stop(); + LOG_destory(); } diff --git a/src/Ichor/main.cpp b/src/Ichor/main.cpp index 1206df1..94e7770 100644 --- a/src/Ichor/main.cpp +++ b/src/Ichor/main.cpp @@ -1,140 +1,135 @@ +#include +#include +#include #include #include -#include #include -#include -#include -#include "util/comm.h" -#include "util/array.h" -#include "log/log.h" -#include "sub/sub.h" -#include "socket/socket.h" -#include "arm/arm.h" -#include "conf/config.h" #include "api/api.h" - +#include "arm/arm.h" #include "arm/ichor_arm.h" +#include "conf/config.h" #include "conf/ichor_conf.h" +#include "log/log.h" +#include "socket/socket.h" +#include "sub/sub.h" +#include "util/array.h" +#include "util/comm.h" -#define LOG_FILE_THRESHOLD_THIS LOG_THRESHOLD_MAX -#define LOG_CONSOLE_THRESHOLD_THIS LOG_THRESHOLD_MAX +#define LOG_FILE_THRESHOLD_THIS LOG_THRESHOLD_MAX +#define LOG_CONSOLE_THRESHOLD_THIS LOG_THRESHOLD_MAX -const char* app_name; +const char *app_name; volatile int quit_sig = 0; -static void quit_handler(int signum) -{ - quit_sig = signum; // quit control loop +static void quit_handler(int signum) { + quit_sig = signum; // quit control loop } -static int register_intr() -{ - struct sigaction sa; - sa.sa_handler = quit_handler; - sigemptyset(&sa.sa_mask); - sa.sa_flags = SA_RESTART; /* Restart functions if - interrupted by handler */ - - if (sigaction(SIGINT, &sa, NULL) == -1) return -1; - if (sigaction(SIGQUIT, &sa, NULL) == -1) return -1; - if (sigaction(SIGABRT, &sa, NULL) == -1) return -1; - return 0; +static int register_intr() { + struct sigaction sa; + sa.sa_handler = quit_handler; + sigemptyset(&sa.sa_mask); + sa.sa_flags = SA_RESTART; /* Restart functions if + interrupted by handler */ + + if (sigaction(SIGINT, &sa, NULL) == -1) return -1; + if (sigaction(SIGQUIT, &sa, NULL) == -1) return -1; + if (sigaction(SIGABRT, &sa, NULL) == -1) return -1; + return 0; } #if VALGRIND -static void dummy_msg(Subscriber* hermes) -{ - SUB_Buffer* buf = hermes->DequeueBuffer(SUB_QUEUE_FREE); - if (!buf) return; +static void dummy_msg(Subscriber *hermes) { + SUB_Buffer *buf = hermes->DequeueBuffer(SUB_QUEUE_FREE); + if (!buf) return; - API_Data_Wrapper* msg = (API_Data_Wrapper*) &buf->body[0]; + API_Data_Wrapper *msg = (API_Data_Wrapper *)&buf->body[0]; - msg->header.cmd_id = htobe32(0x0); - msg->header.reserved_1 = htobe16(0); - msg->header.cmd_val = htobe16(API_CMD_HOME); - msg->header.len = htobe16(sizeof(API_Data_Home)); + msg->header.cmd_id = htobe32(0x0); + msg->header.reserved_1 = htobe16(0); + msg->header.cmd_val = htobe16(API_CMD_HOME); + msg->header.len = htobe16(sizeof(API_Data_Home)); - API_Data_Home* cmd = (API_Data_Home*) &msg->payload_head; + API_Data_Home *cmd = (API_Data_Home *)&msg->payload_head; - cmd->delay_ms = 0; + cmd->delay_ms = 0; - buf->len = sizeof(API_Data_Home) + sizeof(API_Data_Header) + 2; - hermes->EnqueueBuffer(SUB_QUEUE_COMMAND, buf); + buf->len = sizeof(API_Data_Home) + sizeof(API_Data_Header) + 2; + hermes->EnqueueBuffer(SUB_QUEUE_COMMAND, buf); } #endif -int main(int argc, char* argv[]) -{ - LOG_prep(); - app_name = argv[0]; - register_intr(); +int main(int argc, char *argv[]) { + LOG_prep(); + app_name = argv[0]; + register_intr(); - // Initalize program; Setup Logging - IchorConfig conf = IchorConfig(); + // Initalize program; Setup Logging + IchorConfig conf = IchorConfig(); - // Setup config priority - const char* conf_loc[] = {NULL, CONF_DEFAULT_LOCATION}; - uint8_t conf_loc_len = UTIL_len(conf_loc); - if (argc > 1) conf_loc[0] = argv[1]; + // Setup config priority + const char *conf_loc[] = {NULL, CONF_DEFAULT_LOCATION}; + uint8_t conf_loc_len = UTIL_len(conf_loc); + if (argc > 1) conf_loc[0] = argv[1]; - for (uint8_t iter = 0; iter < conf_loc_len; iter++) - if(conf_loc[iter] && !conf.SetFilePath(conf_loc[iter])) - break; // If file is successfully set, break loop + for (uint8_t iter = 0; iter < conf_loc_len; iter++) + if (conf_loc[iter] && !conf.SetFilePath(conf_loc[iter])) + break; // If file is successfully set, break loop - conf.ParseConfig(); + conf.ParseConfig(); - LOG_init(conf.GetLogLocation()); - LOG_start(); + LOG_init(conf.GetLogLocation()); + LOG_start(); - conf.DumpToLog(LOG_INFO); + conf.DumpToLog(LOG_INFO); - // Init Modules - Subscriber hermes = Subscriber(); + // Init Modules + Subscriber hermes = Subscriber(); - #if 0 +#if 0 Inbox* inbox = new TAMQ_Consumer( conf.GetBrokerAddress(), conf.GetCommandURI(), conf.GetUseTopics(), conf.GetClientAck()); - #else - Inbox* inbox = new Socket(); - #endif - - // Register hardware - Ichor* bot = new Ichor("/dev/gpiochip0", "/dev/i2c-1", 0x60, 0x61, 0x62); - // bot->RegisterMotor(0, 0, 0, 1, 14, 4, 17, 0); // Base - bot->RegisterMotor(0, 0, 4, 3, 2, 4, 17, 0); // Base - bot->RegisterMotor(2, 0, 11, 12, 13, 22, 23, 2); // Elbow - bot->Init(); - - // Register modules - inbox->RegisterSubscriber(&hermes); - bot->RegisterSubscriber(&hermes); - - // Start - hermes.Start(); - if(-1 == bot->Start()) quit_handler(SIGABRT); - inbox->Start(); - - // Loop - if (!quit_sig) LOG_INFO("Ready."); - while(!quit_sig); - LOG_VERBOSE(0, "Quit signal: %d", quit_sig); - LOG_INFO("Shutting down..."); - - // Cleanup running processes - inbox->Stop(); - hermes.Stop(); - bot->Stop(); - - // Release resources - delete bot; - delete inbox; - - // End demo - LOG_INFO("End Program."); - LOG_stop(); - LOG_destory(); +#else + Inbox *inbox = new Socket(); +#endif + + // Register hardware + Ichor *bot = new Ichor("/dev/gpiochip0", "/dev/i2c-1", 0x60, 0x61, 0x62); + // bot->RegisterMotor(0, 0, 0, 1, 14, 4, 17, 0); // Base + bot->RegisterMotor(0, 0, 4, 3, 2, 4, 17, 0); // Base + bot->RegisterMotor(2, 0, 11, 12, 13, 22, 23, 2); // Elbow + bot->Init(); + + // Register modules + inbox->RegisterSubscriber(&hermes); + bot->RegisterSubscriber(&hermes); + + // Start + hermes.Start(); + if (-1 == bot->Start()) quit_handler(SIGABRT); + inbox->Start(); + + // Loop + if (!quit_sig) LOG_INFO("Ready."); + while (!quit_sig); + LOG_VERBOSE(0, "Quit signal: %d", quit_sig); + LOG_INFO("Shutting down..."); + + // Cleanup running processes + inbox->Stop(); + hermes.Stop(); + bot->Stop(); + + // Release resources + delete bot; + delete inbox; + + // End demo + LOG_INFO("End Program."); + LOG_stop(); + LOG_destory(); } \ No newline at end of file diff --git a/src/common/api/api.c b/src/common/api/api.c index d4803ac..dbf60b6 100644 --- a/src/common/api/api.c +++ b/src/common/api/api.c @@ -1,81 +1,79 @@ -#include +#include "api/api.h" + #include #include +#include -#include "api/api.h" #include "api/api_private.h" -#include "util/comm.h" #include "util/array.h" +#include "util/comm.h" -#define LOG_CONSOLE_THRESHOLD_THIS LOG_THRESHOLD_MAX -#define LOG_FILE_THRESHOLD_THIS LOG_THRESHOLD_MAX +#define LOG_CONSOLE_THRESHOLD_THIS LOG_THRESHOLD_MAX +#define LOG_FILE_THRESHOLD_THIS LOG_THRESHOLD_MAX -int API_prep_polar_pan(API_Data_Polar_Pan* payload) -{ - if (!payload) STD_FAIL; +int API_prep_polar_pan(API_Data_Polar_Pan *payload) { + if (!payload) STD_FAIL; - payload->delta_altitude = be32toh(payload->delta_altitude); - payload->delta_azimuth = be32toh(payload->delta_azimuth); - payload->delay_ms = be32toh(payload->delay_ms); - payload->time_ms = be32toh(payload->time_ms); + payload->delta_altitude = be32toh(payload->delta_altitude); + payload->delta_azimuth = be32toh(payload->delta_azimuth); + payload->delay_ms = be32toh(payload->delay_ms); + payload->time_ms = be32toh(payload->time_ms); - return 0; + return 0; } -int API_prep_home(API_Data_Home* payload) -{ - if (!payload) STD_FAIL; +int API_prep_home(API_Data_Home *payload) { + if (!payload) STD_FAIL; - payload->delay_ms = be32toh(payload->delay_ms); + payload->delay_ms = be32toh(payload->delay_ms); - return 0; + return 0; } -int API_validate_command (const uint8_t *buf, uint16_t len) -{ - // Check inputs - if (!buf) STD_FAIL; - API_Data_Wrapper *cmd = (API_Data_Wrapper *) buf; - - // Fix endianness - cmd->header.cmd_id = be32toh(cmd->header.cmd_id); - cmd->header.cmd_val = be16toh(cmd->header.cmd_val); - cmd->header.len = be16toh(cmd->header.len); - - // TODO: Check for duplicate cmd_ids - - // Check length - if (len < sizeof(API_Data_Header) + cmd->header.len) STD_FAIL - - // Command specific preparation - switch (cmd->header.cmd_val) - { - // Intentional fallthrough - case API_CMD_HANDSHAKE: - // No body; Always valid - case API_CMD_POLARPAN_START: - // Already correct endianness - case API_CMD_POLARPAN_STOP: - // Already correct endianness - break; - - case API_CMD_POLARPAN: - API_prep_polar_pan((API_Data_Polar_Pan*) &cmd->payload_head); - break; - case API_CMD_HOME: - API_prep_home((API_Data_Home *) &cmd->payload_head); - break; - default: - LOG_ERROR ( - "API: Failed to process Command ID %d: Unrecognized Command Value: %d", - cmd->header.cmd_id, cmd->header.cmd_val); - return -1; - } - - // Check CRC - // TODO: Implement - uint16_t *crc = (uint16_t*) (&cmd->payload_head + cmd->header.len); - *crc = be16toh(*crc); - - return 0; +int API_validate_command(const uint8_t *buf, uint16_t len) { + // Check inputs + if (!buf) STD_FAIL; + API_Data_Wrapper *cmd = (API_Data_Wrapper *)buf; + + // Fix endianness + cmd->header.cmd_id = be32toh(cmd->header.cmd_id); + cmd->header.cmd_val = be16toh(cmd->header.cmd_val); + cmd->header.len = be16toh(cmd->header.len); + + // TODO: Check for duplicate cmd_ids + + // Check length + if (len < sizeof(API_Data_Header) + cmd->header.len) STD_FAIL + + // Command specific preparation + switch (cmd->header.cmd_val) { + // Intentional fallthrough + case API_CMD_HANDSHAKE: + // No body; Always valid + case API_CMD_POLARPAN_START: + // Already correct endianness + case API_CMD_POLARPAN_STOP: + // Already correct endianness + break; + + case API_CMD_POLARPAN: + API_prep_polar_pan((API_Data_Polar_Pan *)&cmd->payload_head); + break; + case API_CMD_HOME: + API_prep_home((API_Data_Home *)&cmd->payload_head); + break; + default: + LOG_ERROR( + "API: Failed to process Command ID %d: Unrecognized Command Value: " + "%d", + cmd->header.cmd_id, cmd->header.cmd_val); + return -1; + } + + // Check CRC + // TODO: Implement + uint16_t *crc = (uint16_t *)(&cmd->payload_head + cmd->header.len); + *crc = be16toh(*crc); + + return 0; } \ No newline at end of file diff --git a/src/common/api/api.h b/src/common/api/api.h index e36ffab..f5435e2 100644 --- a/src/common/api/api.h +++ b/src/common/api/api.h @@ -1,6 +1,6 @@ /** * ICD Compliant Message processor -*/ + */ #pragma once @@ -10,64 +10,65 @@ extern "C" { #endif -typedef enum _api_cmd_id -{ - API_CMD_HANDSHAKE = 0x0000, - API_CMD_POLARPAN = 0x0001, - API_CMD_HOME = 0x0002, - API_CMD_POLARPAN_START = 0x0003, - API_CMD_POLARPAN_STOP = 0x0004, +typedef enum _api_cmd_id { + API_CMD_HANDSHAKE = 0x0000, + API_CMD_POLARPAN = 0x0001, + API_CMD_HOME = 0x0002, + API_CMD_POLARPAN_START = 0x0003, + API_CMD_POLARPAN_STOP = 0x0004, + API_CMD_SET_SPEED = 0x0005, + API_CMD_GET_SPEED = 0x0006, } API_Command_ID; #pragma pack(push, 1) /** Struct mapping command message header values */ -typedef struct _api_data_wrapper_header -{ - uint32_t cmd_id; /** Unique ID for individual commands */ - uint16_t reserved_1; /** RESERVED */ - uint16_t cmd_val; /** Command for device to carry out */ - uint16_t len; /** Length of Payload */ +typedef struct _api_data_wrapper_header { + uint32_t cmd_id; /** Unique ID for individual commands */ + uint16_t reserved_1; /** RESERVED */ + uint16_t cmd_val; /** Command for device to carry out */ + uint16_t len; /** Length of Payload */ } API_Data_Header; /** Wrapper Struct */ -typedef struct _api_data_wrapper -{ - API_Data_Header header; - uint8_t payload_head; /** Command Info */ +typedef struct _api_data_wrapper { + API_Data_Header header; + uint8_t payload_head; /** Command Info */ } API_Data_Wrapper; -typedef struct _api_data_polar_pan -{ - int32_t delta_azimuth; /** Requested change in azimuth */ - int32_t delta_altitude; /** Requested change in altitude */ - uint32_t delay_ms; /** How long to wait until executing pan */ - uint32_t time_ms; /** How long the pan should take to execute */ +typedef struct _api_data_polar_pan { + int32_t delta_azimuth; /** Requested change in azimuth */ + int32_t delta_altitude; /** Requested change in altitude */ + uint32_t delay_ms; /** How long to wait until executing pan */ + uint32_t time_ms; /** How long the pan should take to execute */ } API_Data_Polar_Pan; -typedef struct _api_data_polar_pan_start -{ - int8_t delta_azimuth; /** Requested change in azimuth */ - int8_t delta_altitude; /** Requested change in altitude */ +typedef struct _api_data_polar_pan_start { + int8_t delta_azimuth; /** Requested change in azimuth */ + int8_t delta_altitude; /** Requested change in altitude */ } API_Data_Polar_Pan_Start; -typedef struct _api_data_home -{ - uint32_t delay_ms; /** How long to wait until executing pan */ +typedef struct _api_data_home { + uint32_t delay_ms; /** How long to wait until executing pan */ } API_Data_Home; + +typedef struct _api_data_set_speed { + uint8_t speed; /** Speed value 0-100 */ +} API_Data_Set_Speed; + #pragma pack(pop) #define API_WRAPPER_HEAD_LEN offsetof(API_Data_Wrapper, payload_head) /** * @brief Checks to see if a command is valid and can be processed safely - * @details Fixes endianness, Checks validity of inputs, + * @details Fixes endianness, Checks validity of inputs, * and the length and CRC of the provided input * @param buf Byte buffer * @param len Length of byte buffer * @returns 0 on success, -1 on failure -*/ -int API_validate_command (const uint8_t *buf, uint16_t len); + */ +int API_validate_command(const uint8_t *buf, uint16_t len); #ifdef __cplusplus } -#endif \ No newline at end of file +#endif diff --git a/src/common/api/api_private.h b/src/common/api/api_private.h index d12e0f0..d75b708 100644 --- a/src/common/api/api_private.h +++ b/src/common/api/api_private.h @@ -1,6 +1,6 @@ /** - * -*/ + * + */ #pragma once #include @@ -17,15 +17,15 @@ extern "C" { * @brief validates the payload of a Polar Pan command message * @param payload Pointer to Polar Pan command payload * @returns 0 on success, -1 on failure -*/ -int API_prep_polar_pan(API_Data_Polar_Pan* payload); + */ +int API_prep_polar_pan(API_Data_Polar_Pan *payload); /** * @brief validates the payload of a Home command message * @param payload Pointer to Polar Pan command payload * @returns 0 on success, -1 on failure -*/ -int API_prep_home(API_Data_Home* payload); + */ +int API_prep_home(API_Data_Home *payload); #ifdef __cplusplus } diff --git a/src/common/arm/arm.cpp b/src/common/arm/arm.cpp index 94e04e0..dff7dca 100644 --- a/src/common/arm/arm.cpp +++ b/src/common/arm/arm.cpp @@ -1,108 +1,102 @@ -#include +#include "arm/arm.h" + #include +#include #include -#include "arm/arm.h" #include "api/api.h" #include "log/log.h" #include "util/comm.h" -#define LOG_CONSOLE_THRESHOLD_THIS LOG_THRESHOLD_MAX -#define LOG_FILE_THRESHOLD_THIS LOG_THRESHOLD_MAX +#define LOG_CONSOLE_THRESHOLD_THIS LOG_THRESHOLD_MAX +#define LOG_FILE_THRESHOLD_THIS LOG_THRESHOLD_MAX -Arm::Arm() -{ - thread_enable = false; -} +Arm::Arm() { thread_enable = false; } -Arm::~Arm() -{ -} +Arm::~Arm() {} -bool Arm::GetThreadEnable() -{ - return this->thread_enable; -} +bool Arm::GetThreadEnable() { return this->thread_enable; } + +static void *ARM_run(void *arg) { + Arm *arm = (Arm *)arg; -static void* ARM_run(void* arg) -{ - Arm* arm = (Arm*) arg; - - // TODO: Add exit code - while(1) - { - int ret = arm->ProcessQueue(); - if (1 == ret) - { - arm->Poll(); - if (!arm->GetThreadEnable()) break; - usleep(ARM_POLL_PERIOD_MS * 1000); - continue; - } + // TODO: Add exit code + while (1) { + int ret = arm->ProcessQueue(); + if (1 == ret) { + arm->Poll(); + if (!arm->GetThreadEnable()) break; + usleep(ARM_POLL_PERIOD_MS * 1000); + continue; } + } - return 0; + return 0; } -int Arm::Start() -{ - thread_enable = true; - int ret = pthread_create(&this->pid, NULL, ARM_run, this); - if (ret == -1) STD_FAIL; - return 0; +int Arm::Start() { + thread_enable = true; + int ret = pthread_create(&this->pid, NULL, ARM_run, this); + if (ret == -1) STD_FAIL; + return 0; } -int Arm::Stop() -{ - this->thread_enable = 0; - pthread_join(pid, NULL); - return 0; +int Arm::Stop() { + this->thread_enable = 0; + pthread_join(pid, NULL); + return 0; } -int Arm::RegisterSubscriber(Subscriber* sub) -{ - if (!sub) STD_FAIL; - this->sub = sub; - return 0; +int Arm::RegisterSubscriber(Subscriber *sub) { + if (!sub) STD_FAIL; + this->sub = sub; + return 0; } -int Arm::ProcessQueue() -{ - SUB_Buffer* buf = sub->DequeueBuffer(SUB_QUEUE_COMMAND); - - if (!buf) return 1; - if (API_validate_command(&buf->body[0], buf->len)) STD_FAIL; - API_Data_Wrapper *cmd = (API_Data_Wrapper *) &buf->body; - - int status = 0; - switch (cmd->header.cmd_val) - { - case API_CMD_HANDSHAKE: - LOG_INFO("Handshake Recieved"); - if (HandShake()) STD_FAIL; - break; - case API_CMD_POLARPAN: - LOG_INFO("Polar Pan Recieved"); - if (PolarPan((API_Data_Polar_Pan *) &cmd->payload_head)) STD_FAIL; - break; - case API_CMD_HOME: - LOG_INFO("Home Received"); - if (Home((API_Data_Home *)&cmd->payload_head)) STD_FAIL; - break; - case API_CMD_POLARPAN_START: - LOG_INFO("Polar Pan Start Recieved"); - if (PolarPanStart((API_Data_Polar_Pan_Start *) &cmd->payload_head)) STD_FAIL; - break; - case API_CMD_POLARPAN_STOP: - LOG_INFO("Polar Pan Stop Recieved"); - if (PolarPanStop()) STD_FAIL; - break; - default: - LOG_IEC(); - status = -1; - break; - } +int Arm::ProcessQueue() { + SUB_Buffer *buf = sub->DequeueBuffer(SUB_QUEUE_COMMAND); + + if (!buf) return 1; + if (API_validate_command(&buf->body[0], buf->len)) STD_FAIL; + API_Data_Wrapper *cmd = (API_Data_Wrapper *)&buf->body; + + int status = 0; + switch (cmd->header.cmd_val) { + case API_CMD_HANDSHAKE: + LOG_INFO("Handshake Recieved"); + if (HandShake()) STD_FAIL; + break; + case API_CMD_POLARPAN: + LOG_INFO("Polar Pan Recieved"); + if (PolarPan((API_Data_Polar_Pan *)&cmd->payload_head)) STD_FAIL; + break; + case API_CMD_HOME: + LOG_INFO("Home Received"); + if (Home((API_Data_Home *)&cmd->payload_head)) STD_FAIL; + break; + case API_CMD_POLARPAN_START: + LOG_INFO("Polar Pan Start Recieved"); + if (PolarPanStart((API_Data_Polar_Pan_Start *)&cmd->payload_head)) + STD_FAIL; + break; + case API_CMD_POLARPAN_STOP: + LOG_INFO("Polar Pan Stop Recieved"); + if (PolarPanStop()) STD_FAIL; + break; + case API_CMD_SET_SPEED: + LOG_INFO("Set Speed Recieved"); + if (SetSpeed((API_Data_Set_Speed *)&cmd->payload_head)) STD_FAIL; + break; + case API_CMD_GET_SPEED: + LOG_INFO("Get Speed Recieved"); + if (GetSpeed()) STD_FAIL; + break; + default: + LOG_IEC(); + status = -1; + break; + } - sub->EnqueueBuffer(SUB_QUEUE_FREE, buf); - return status; + sub->EnqueueBuffer(SUB_QUEUE_FREE, buf); + return status; } diff --git a/src/common/arm/arm.h b/src/common/arm/arm.h index 5d9f039..f370e95 100644 --- a/src/common/arm/arm.h +++ b/src/common/arm/arm.h @@ -1,59 +1,61 @@ /** * Generic, Hardware Agnostic Arm Interface -*/ + */ #pragma once -#include #include +#include -#include "sub/sub.h" #include "api/api.h" +#include "sub/sub.h" #define ARM_POLL_PERIOD_MS (25) -class Arm -{ -private: - pthread_t pid; - bool thread_enable; - Subscriber* sub; - - virtual int HandShake() = 0; - virtual int PolarPan(API_Data_Polar_Pan *pan) = 0; - virtual int PolarPanStart(API_Data_Polar_Pan_Start *pan) = 0; - virtual int PolarPanStop() = 0; - virtual int Home(API_Data_Home* home) = 0; - -public: - enum OversteerConfig - { - OVERSTEER_NONE, - OVERSTEER_IGNORE, - OVERSTEER_ABORT, - }; - - Arm(); - virtual ~Arm(); - - // Thread control - int Start(); - int Stop(); - - bool GetThreadEnable(); - - /** - * @brief If there's a buffer in the command queue, it will be processed - * @returns 0 a buffer has processed properly, 1 if there is no buffer, -1 on failure - */ - int ProcessQueue(); - int RegisterSubscriber(Subscriber* sub); - - /** - * @brief Function that is called by the parent Arm thread in a timed loop; - * Used miscellaneous tasks that need to be regularly executed. - * @details Primary purpose is to log data received from Scorbot. - * Flushes buffer after receiving a line terminator, or after a fixed length of time - */ - virtual void Poll() = 0; -}; \ No newline at end of file +class Arm { + private: + pthread_t pid; + bool thread_enable; + Subscriber *sub; + + virtual int HandShake() = 0; + virtual int PolarPan(API_Data_Polar_Pan *pan) = 0; + virtual int PolarPanStart(API_Data_Polar_Pan_Start *pan) = 0; + virtual int PolarPanStop() = 0; + virtual int Home(API_Data_Home *home) = 0; + virtual int SetSpeed(API_Data_Set_Speed *speed) = 0; + virtual int GetSpeed() = 0; + + public: + enum OversteerConfig { + OVERSTEER_NONE, + OVERSTEER_IGNORE, + OVERSTEER_ABORT, + }; + + Arm(); + virtual ~Arm(); + + // Thread control + int Start(); + int Stop(); + + bool GetThreadEnable(); + + /** + * @brief If there's a buffer in the command queue, it will be processed + * @returns 0 a buffer has processed properly, 1 if there is no buffer, -1 on + * failure + */ + int ProcessQueue(); + int RegisterSubscriber(Subscriber *sub); + + /** + * @brief Function that is called by the parent Arm thread in a timed loop; + * Used miscellaneous tasks that need to be regularly executed. + * @details Primary purpose is to log data received from Scorbot. + * Flushes buffer after receiving a line terminator, or after a fixed length + * of time + */ + virtual void Poll() = 0; +}; diff --git a/src/common/conf/config.cpp b/src/common/conf/config.cpp index 8c1d641..b964caf 100644 --- a/src/common/conf/config.cpp +++ b/src/common/conf/config.cpp @@ -1,347 +1,318 @@ -#include +#include "conf/config.h" + +#include +#include +#include #include #include -#include -#include +#include #include -#include -#include +#include -#include "conf/config.h" -#include "util/comm.h" #include "log/log.h" +#include "util/comm.h" -#define LOG_CONSOLE_THRESHOLD_THIS LOG_THRESHOLD_DEFAULT -#define LOG_FILE_THRESHOLD_THIS LOG_THRESHOLD_MAX +#define LOG_CONSOLE_THRESHOLD_THIS LOG_THRESHOLD_DEFAULT +#define LOG_FILE_THRESHOLD_THIS LOG_THRESHOLD_MAX -Config::Config() -{ - conf_errno = 0; - ClearKeyVals(); +Config::Config() { + conf_errno = 0; + ClearKeyVals(); } -Config::~Config() -{ - ClearKeyVals(); -} +Config::~Config() { ClearKeyVals(); } /** * @brief Helper function to initalize configuration entry * @param entry Entry to initialize * @returns 0 on success, -1 on failure -*/ -static int CONF_Entry_init(CONF_Entry *entry) -{ - if (!entry) STD_FAIL; - memset(entry, 0, sizeof(CONF_Entry)); - return 0; + */ +static int CONF_Entry_init(CONF_Entry *entry) { + if (!entry) STD_FAIL; + memset(entry, 0, sizeof(CONF_Entry)); + return 0; } -const char* Config::GetFilePath() -{ - return &path[0]; -} +const char *Config::GetFilePath() { return &path[0]; } -int Config::SetFilePath(const char* file_path) -{ - if (!file_path) STD_FAIL; +int Config::SetFilePath(const char *file_path) { + if (!file_path) STD_FAIL; - if (strlen(file_path) >= CONF_MEMBER_LEN) - { - LOG_WARN("Config path too long; Max path length: %d", CONF_MEMBER_LEN); - return -1; - } + if (strlen(file_path) >= CONF_MEMBER_LEN) { + LOG_WARN("Config path too long; Max path length: %d", CONF_MEMBER_LEN); + return -1; + } - if (access(file_path, F_OK)) - { - LOG_WARN("Error setting config file: \"%s\": Does not exist.", file_path); - return -1; - } + if (access(file_path, F_OK)) { + LOG_WARN("Error setting config file: \"%s\": Does not exist.", file_path); + return -1; + } - if (access(file_path, R_OK)) - { - LOG_WARN("Error setting config file: \"%s\": Permission denied.", file_path); - return -1; - } + if (access(file_path, R_OK)) { + LOG_WARN("Error setting config file: \"%s\": Permission denied.", + file_path); + return -1; + } - strcpy(&this->path[0], file_path); - LOG_VERBOSE(0, "Config file set: %s", file_path); - return 0; + strcpy(&this->path[0], file_path); + LOG_VERBOSE(0, "Config file set: %s", file_path); + return 0; } /** * @brief Helper function for determining line terminators * @returns 1 for terminator, 0 otherwise -*/ -static int is_term(char ch) -{ - switch ((signed char) ch) - { - //Intentional fallthroughs - case '\n': - case '\0': - case EOF: - return 1; - default: - break; - } - return 0; + */ +static int is_term(char ch) { + switch ((signed char)ch) { + // Intentional fallthroughs + case '\n': + case '\0': + case EOF: + return 1; + default: + break; + } + return 0; } /** - * @brief Helper function for copying the contents of a regex match to a char buffer + * @brief Helper function for copying the contents of a regex match to a char + * buffer * @param dst Destination char buffer * @param src Original string from which matches are extracted * @param group Match information -*/ -static void copy_regex_group(char* dst, const char* src, regmatch_t* group) -{ - uint8_t match_len = group->rm_eo - group->rm_so; - strncpy(&dst[0], &src[group->rm_so], match_len); - dst[match_len] = '\0'; + */ +static void copy_regex_group(char *dst, const char *src, regmatch_t *group) { + uint8_t match_len = group->rm_eo - group->rm_so; + strncpy(&dst[0], &src[group->rm_so], match_len); + dst[match_len] = '\0'; } -int Config::GetKeyIndex(const char* key) -{ - int16_t idx = -1; - for (uint8_t iter = 0; iter < key_count; iter++) - { - if(0 == strcmp(key, &pairs[iter].key[0])) - { - idx = iter; - break; - } +int Config::GetKeyIndex(const char *key) { + int16_t idx = -1; + for (uint8_t iter = 0; iter < key_count; iter++) { + if (0 == strcmp(key, &pairs[iter].key[0])) { + idx = iter; + break; } + } - return idx; + return idx; } -int Config::ParseYaml(int fd) -{ - // Key pairs are assumed to be in ": " format, with a newline, null terminator, or end-of-file after each value - // read function uses system call; minimize using buffers as much as possible - - regex_t entry; // Compiled regex pattern for detecting config entries - regmatch_t matches[3]; // Match groups for regex - uint8_t line = 1; // Tracks line number for logging/debugging - off_t offset; // Tracks how far to back track for next read; used to line up to just after the first newline in the buffer - char buffer[CONF_KEY_LEN + CONF_VAL_LEN + 4]; // buffer to store read calls in; ": " and "\n\0" require 4 additional characters - char key[CONF_KEY_LEN]; // buffer to temporarily hold keys/vals - int result = 0; // result of each read - - memset(&buffer[0], 0, sizeof(buffer)); - if (0 != regcomp(&entry, CONF_ENTRY_FMT, CONF_REGEX_FLAGS)) STD_FAIL; // Compile regex pattern - while(3 <= (result = read(fd, &buffer[0], sizeof(buffer) - 1))) // Loop until file is empty - { - LOG_VERBOSE(5, "RESULT: %d", result); - LOG_VERBOSE(6, "BUFFER: %s", buffer); - - buffer[result] = '\0'; // Null terminate buffer for str operations - int ret = regexec(&entry, &buffer[0], 3, matches, 0); // match regex pattern against read buffer - if(!ret) - { - // Match found - copy_regex_group(&key[0], &buffer[0], &matches[1]); - int idx = GetKeyIndex(&key[0]); - LOG_VERBOSE(4, "KEY: %s", key); - LOG_VERBOSE(5, "Key Index: %d", idx); - - - if (-1 == idx) - { - LOG_VERBOSE(4, "Unrecognized key; Moving on"); - } - else - { - char* val = &pairs[idx].val[0]; - copy_regex_group(val, &buffer[0], &matches[2]); - LOG_VERBOSE(4, "VAL: %s", val); - } - - offset = matches[0].rm_eo; // set offset to end of match - } - else - { - LOG_VERBOSE(4, "NO MATCH ON LINE %d", line); - for (offset = 0; offset < result && !is_term(buffer[offset]); offset++); // Sets offset to first newline in buffer - } - - offset -= result - 1; - LOG_VERBOSE(6, "OFFSET: %d", offset); - memset(buffer, 0, sizeof(buffer)); // Clear buffer - lseek(fd, offset, SEEK_CUR); // Align file iterator to just after first newline in buffer - line++; // Increment line counter +int Config::ParseYaml(int fd) { + // Key pairs are assumed to be in ": " format, with a newline, null + // terminator, or end-of-file after each value read function uses system call; + // minimize using buffers as much as possible + + regex_t entry; // Compiled regex pattern for detecting config entries + regmatch_t matches[3]; // Match groups for regex + uint8_t line = 1; // Tracks line number for logging/debugging + off_t offset; // Tracks how far to back track for next read; used to line up + // to just after the first newline in the buffer + char buffer[CONF_KEY_LEN + CONF_VAL_LEN + + 4]; // buffer to store read calls in; ": " and "\n\0" require 4 + // additional characters + char key[CONF_KEY_LEN]; // buffer to temporarily hold keys/vals + int result = 0; // result of each read + + memset(&buffer[0], 0, sizeof(buffer)); + if (0 != regcomp(&entry, CONF_ENTRY_FMT, CONF_REGEX_FLAGS)) + STD_FAIL; // Compile regex pattern + while (3 <= (result = read(fd, &buffer[0], + sizeof(buffer) - 1))) // Loop until file is empty + { + LOG_VERBOSE(5, "RESULT: %d", result); + LOG_VERBOSE(6, "BUFFER: %s", buffer); + + buffer[result] = '\0'; // Null terminate buffer for str operations + int ret = regexec(&entry, &buffer[0], 3, matches, + 0); // match regex pattern against read buffer + if (!ret) { + // Match found + copy_regex_group(&key[0], &buffer[0], &matches[1]); + int idx = GetKeyIndex(&key[0]); + LOG_VERBOSE(4, "KEY: %s", key); + LOG_VERBOSE(5, "Key Index: %d", idx); + + if (-1 == idx) { + LOG_VERBOSE(4, "Unrecognized key; Moving on"); + } else { + char *val = &pairs[idx].val[0]; + copy_regex_group(val, &buffer[0], &matches[2]); + LOG_VERBOSE(4, "VAL: %s", val); + } + + offset = matches[0].rm_eo; // set offset to end of match + } else { + LOG_VERBOSE(4, "NO MATCH ON LINE %d", line); + for (offset = 0; offset < result && !is_term(buffer[offset]); + offset++); // Sets offset to first newline in buffer } - regfree(&entry); - return 0; + offset -= result - 1; + LOG_VERBOSE(6, "OFFSET: %d", offset); + memset(buffer, 0, sizeof(buffer)); // Clear buffer + lseek( + fd, offset, + SEEK_CUR); // Align file iterator to just after first newline in buffer + line++; // Increment line counter + } + + regfree(&entry); + return 0; } -int Config::ParseConfig() -{ - if (0 == strlen(path)) STD_FAIL; - int fd = open(path, CONF_FILE_PERM); - if (fd < 0) - { - conf_errno = errno; - return -1; - } +int Config::ParseConfig() { + if (0 == strlen(path)) STD_FAIL; + int fd = open(path, CONF_FILE_PERM); + if (fd < 0) { + conf_errno = errno; + return -1; + } - ParseYaml(fd); + ParseYaml(fd); - if(close(fd)) STD_FAIL; - return 0; + if (close(fd)) STD_FAIL; + return 0; } -int Config::AddKey(const char* key, const char* deflt, CONF_Data_Type type) -{ - if (!key) STD_FAIL; - if (!deflt) STD_FAIL; - if (CONF_PAIR_LIMIT <= key_count) STD_FAIL; +int Config::AddKey(const char *key, const char *deflt, CONF_Data_Type type) { + if (!key) STD_FAIL; + if (!deflt) STD_FAIL; + if (CONF_PAIR_LIMIT <= key_count) STD_FAIL; - pairs[key_count].type = type; - strcpy(&pairs[key_count].key[0], key); - strcpy(&pairs[key_count].val[0], deflt); - return key_count++; + pairs[key_count].type = type; + strcpy(&pairs[key_count].key[0], key); + strcpy(&pairs[key_count].val[0], deflt); + return key_count++; } -int Config::AddKey(const char* key, const char* deflt) -{ - return AddKey(key, deflt, CONF_DATA_STRING); +int Config::AddKey(const char *key, const char *deflt) { + return AddKey(key, deflt, CONF_DATA_STRING); } -int Config::AddKey(const char* key, int deflt) -{ - char val[10]; - sprintf(&val[0], "%d", deflt); - return AddKey(key, val, CONF_DATA_INT); +int Config::AddKey(const char *key, int deflt) { + char val[10]; + sprintf(&val[0], "%d", deflt); + return AddKey(key, val, CONF_DATA_INT); } -int Config::AddKey(const char* key, bool deflt) -{ - return AddKey(key, deflt ? "true" : "false", CONF_DATA_BOOL); +int Config::AddKey(const char *key, bool deflt) { + return AddKey(key, deflt ? "true" : "false", CONF_DATA_BOOL); } -const char* Config::GetVal(uint8_t idx) -{ - if (idx >= key_count) STD_FAIL_VOID_PTR; - return &pairs[idx].val[0]; +const char *Config::GetVal(uint8_t idx) { + if (idx >= key_count) STD_FAIL_VOID_PTR; + return &pairs[idx].val[0]; } -const char* Config::GetVal(const char* key) -{ - if (!key) STD_FAIL_VOID_PTR; +const char *Config::GetVal(const char *key) { + if (!key) STD_FAIL_VOID_PTR; - int idx = GetKeyIndex(key); - if (-1 == idx) return NULL; - return GetVal(idx); + int idx = GetKeyIndex(key); + if (-1 == idx) return NULL; + return GetVal(idx); } -bool Config::fail_get_bool(int idx) -{ - // Ensure in bounds - if(idx >= 0 && idx < key_count) - { - // Must be invalid value; not "true" or "false" - if (OverrideValue(idx, CONF_DEFAULT_BOOL_VAL)) LOG_IEC(); - LOG_WARN("Unrecognized configuration value for key: \"%s\"; Using default value: %s%", - pairs[idx].key, pairs[idx].val); - } - - return CONF_DEFAULT_BOOL_VAL; +bool Config::fail_get_bool(int idx) { + // Ensure in bounds + if (idx >= 0 && idx < key_count) { + // Must be invalid value; not "true" or "false" + if (OverrideValue(idx, CONF_DEFAULT_BOOL_VAL)) LOG_IEC(); + LOG_WARN( + "Unrecognized configuration value for key: \"%s\"; Using default " + "value: %s%", + pairs[idx].key, pairs[idx].val); + } + + return CONF_DEFAULT_BOOL_VAL; } -bool Config::GetBool(int idx) -{ - if (idx < 0 || idx >= key_count) - { - LOG_IEC(); - return fail_get_bool(idx); - } +bool Config::GetBool(int idx) { + if (idx < 0 || idx >= key_count) { + LOG_IEC(); + return fail_get_bool(idx); + } - const char* val = GetVal(idx); - bool set; + const char *val = GetVal(idx); + bool set; - if (0 == strcmp(val, "true")) - set = true; + if (0 == strcmp(val, "true")) + set = true; - else if (0 == strcmp(val, "false")) - set = false; + else if (0 == strcmp(val, "false")) + set = false; - else - set = fail_get_bool(idx); + else + set = fail_get_bool(idx); - return set; + return set; } -bool Config::GetBool(const char* key) -{ - if (!key) STD_FAIL; - int idx = GetKeyIndex(key); - if (-1 == idx) STD_FAIL; - return GetBool(idx); +bool Config::GetBool(const char *key) { + if (!key) STD_FAIL; + int idx = GetKeyIndex(key); + if (-1 == idx) STD_FAIL; + return GetBool(idx); } -int Config::GetInt(int idx) -{ - const char* val = GetVal(idx); - if (!val) STD_FAIL; - return atoi(val); +int Config::GetInt(int idx) { + const char *val = GetVal(idx); + if (!val) STD_FAIL; + return atoi(val); } -int Config::GetInt(const char* key) -{ - if (!key) STD_FAIL; - int idx = GetKeyIndex(key); - if (-1 == idx) STD_FAIL; - return GetInt(idx); +int Config::GetInt(const char *key) { + if (!key) STD_FAIL; + int idx = GetKeyIndex(key); + if (-1 == idx) STD_FAIL; + return GetInt(idx); } -void Config::ClearKeyVals() -{ - for(uint8_t iter = 0; iter < CONF_PAIR_LIMIT; iter++) - CONF_Entry_init(&pairs[iter]); +void Config::ClearKeyVals() { + for (uint8_t iter = 0; iter < CONF_PAIR_LIMIT; iter++) + CONF_Entry_init(&pairs[iter]); - key_count = 0; + key_count = 0; } -int Config::OverrideValue(uint8_t key_idx, const char* val) -{ - if (key_idx > key_count) STD_FAIL; - if (!val) STD_FAIL; +int Config::OverrideValue(uint8_t key_idx, const char *val) { + if (key_idx > key_count) STD_FAIL; + if (!val) STD_FAIL; - if (strlen(val) + 1 > CONF_VAL_LEN) - { - LOG_ERROR("Override value for key %s too long", &pairs[key_idx].key[0]); - return -1; - } + if (strlen(val) + 1 > CONF_VAL_LEN) { + LOG_ERROR("Override value for key %s too long", &pairs[key_idx].key[0]); + return -1; + } - strcpy(&pairs[key_idx].val[0], val); - return 0; + strcpy(&pairs[key_idx].val[0], val); + return 0; } -int Config::OverrideValue(uint8_t key_idx, bool val) -{ - const char* str_val = val ? "true" : "false"; - return OverrideValue(key_idx, str_val); +int Config::OverrideValue(uint8_t key_idx, bool val) { + const char *str_val = val ? "true" : "false"; + return OverrideValue(key_idx, str_val); } -void Config::DumpToLog(int log_level) -{ - const char* delim = "============================================================="; - LOG_write(log_level, delim); - LOG_write(log_level, "Config parameters:"); - - if (conf_errno || strlen(path) == 0) - { - if (conf_errno) LOG_ERROR("Error opening config: (%d) %s", conf_errno, strerror(conf_errno)); - else if (strlen(path) == 0) LOG_ERROR("Error opening config: failed to set config path"); - LOG_WARN("Using default values"); - } - LOG_write(log_level, "path: %s", path); - for(uint8_t iter = 0; iter < key_count; iter++) - { - LOG_write(log_level, "%s: %s", pairs[iter].key, pairs[iter].val); - } - LOG_write(log_level, delim); +void Config::DumpToLog(int log_level) { + const char *delim = + "============================================================="; + LOG_write(log_level, delim); + LOG_write(log_level, "Config parameters:"); + + if (conf_errno || strlen(path) == 0) { + if (conf_errno) + LOG_ERROR("Error opening config: (%d) %s", conf_errno, + strerror(conf_errno)); + else if (strlen(path) == 0) + LOG_ERROR("Error opening config: failed to set config path"); + LOG_WARN("Using default values"); + } + LOG_write(log_level, "path: %s", path); + for (uint8_t iter = 0; iter < key_count; iter++) { + LOG_write(log_level, "%s: %s", pairs[iter].key, pairs[iter].val); + } + LOG_write(log_level, delim); } \ No newline at end of file diff --git a/src/common/conf/config.h b/src/common/conf/config.h index 8cbfe12..f210051 100644 --- a/src/common/conf/config.h +++ b/src/common/conf/config.h @@ -1,11 +1,14 @@ /** * Generic Base class for parsing basic configuration files. - * Intended to be very easy to extend into child configuration classes that automatically populate the key list, - * and implement their own accessors/mutators -*/ + * Intended to be very easy to extend into child configuration classes that + * automatically populate the key list, and implement their own + * accessors/mutators + */ #pragma once +#include + #define CONF_DEFAULT_LOCATION "/etc/talos/configs/operator.conf" #define CONF_MEMBER_LEN 128 #define CONF_KEY_LEN 64 @@ -17,188 +20,196 @@ #define CONF_REGEX_FLAGS (REG_NEWLINE | REG_EXTENDED) #define CONF_DEFAULT_BOOL_VAL false -typedef enum _conf_data_type -{ - CONF_DATA_STRING, - CONF_DATA_BOOL, - CONF_DATA_INT, +typedef enum _conf_data_type { + CONF_DATA_STRING, + CONF_DATA_BOOL, + CONF_DATA_INT, } CONF_Data_Type; -typedef struct _conf_entry -{ - char key[CONF_KEY_LEN]; /** Holds the key of the config entry*/ - char val[CONF_VAL_LEN]; /** Holds the value of the config entry*/ - CONF_Data_Type type; /** Holds the type of the config entry*/ +typedef struct _conf_entry { + char key[CONF_KEY_LEN]; /** Holds the key of the config entry*/ + char val[CONF_VAL_LEN]; /** Holds the value of the config entry*/ + CONF_Data_Type type; /** Holds the type of the config entry*/ } CONF_Entry; -class Config -{ - private: - int conf_errno; /** Stores any errors that happen during initialization */ - char path[CONF_MEMBER_LEN]; /** File Path */ - CONF_Entry pairs[CONF_PAIR_LIMIT]; /** Stored pairs */ - uint8_t key_count; /** Length of key-value table*/ - - /** - * @brief Parses file according to YAML standards (more or less) - * @param fd File descriptor of config file - * @returns 0 on success, -1 on failure - */ - int ParseYaml(int fd); - - /** - * @brief Linearly searches through keys table and returns the index of the key - * @details Each entry is offset CONF_KEY_LEN from one another - * @returns index on success, -1 on failure - */ - int GetKeyIndex(const char* key); - - /** - * @brief Helper function or handling an error during GetBool - * @param idx Index of config entry - * @returns Default bool value - */ - bool fail_get_bool(int idx); - - protected: - /** - * @brief Overrides a value in the key-value table at the given index - * @param key_idx index of Key-Value pair to override - * @param val Value to override pair with - * @returns 0 on success, -1 on failure - */ - int OverrideValue(uint8_t key_idx, const char* val); - - /** - * @brief Overrides a value in the key-value table at the given index - * @param key_idx index of Key-Value pair to override - * @param val Value to override pair with - * @returns 0 on success, -1 on failure - */ - int OverrideValue(uint8_t key_idx, bool val); - - public: - Config(); - virtual ~Config(); - - /** - * @brief Returns the path of the active config file - * @returns const pointer to the path member on success, NULL on failure - */ - const char* GetFilePath(); - - /** - * @brief Sets the path of the active config file - * @param path Path to set - * @returns 0 on success, -1 on failure - */ - int SetFilePath(const char* file_path); - - /** - * @brief Parses the selected config file - * @details opens the predesignated path, parses it, then closes; YAML is used as the format - * @returns 0 on success, -1 on failure - */ - int ParseConfig(); - - /** - * @brief Appends a key to the list of keys - * @param key Key to add - * @param deflt Default value of key; Will remain the value in the case of missing key/error - * @param type Data type of the key's value - * @returns -1 on failure, the index of the new key-value pair on success - */ - int AddKey(const char* key, const char* deflt, CONF_Data_Type type); - - /** - * @brief Appends a key to the list of keys - * @details Assumes value is a string - * @param key Key to add - * @param deflt Default value of configuration; (Named to avoid keyword conflict) - * @returns -1 on failure, key index on success - */ - int AddKey(const char* key, const char* deflt); - - /** - * @brief Appends a key to the list of keys - * @details Assumes value is a boolean - * @param key Key to add - * @param deflt Default value of configuration; (Named to avoid keyword conflict) - * @returns -1 on failure, key index on success - */ - int AddKey(const char* key, bool deflt); - - /** - * @brief Appends a key to the list of keys - * @details Assumes value is a integer - * @param key Key to add - * @param deflt Default value of configuration; (Named to avoid keyword conflict) - * @returns -1 on failure, key index on success - */ - int AddKey(const char* key, int deflt); - - - /** - * @brief Returns a const char buffer containing the value associated with the given key index - * @details Uses index to directly access string; Faster than linear search overload - * @param idx Index of value's key - * @returns const char pointer to string on success, NULL on failure - */ - const char* GetVal(uint8_t idx); - - /** - * @brief Copies the associated value of a given key to the destination character pointer - * @details Searches through key list to find value - * @param key Key associated with value - * @returns const char pointer to string on success, NULL on failure - */ - const char* GetVal(const char* key); - - /** - * @brief Returns the value associated with the given index as a bool - * @details Uses index to directly access value, rather than linear search - * @param idx Index of value in key-value table - * @param deflt Default value of configuration - * @returns Boolean value of configuration - */ - bool GetBool(int idx); - - /** - * @brief Returns the value of the given key as a bool - * @details Uses linear search to find and access the value, as opposed to direct access with an index - * @param key Key associated with desired value - * @param deflt Default value of configuration - * @returns Boolean value of configuration - */ - bool GetBool(const char* key); - - /** - * @brief Returns the value associated with the given index as an integer - * @details Uses index to directly access value, rather than linear search - * @param idx Index of value in key-value table - * @param deflt Default value of configuration - * @returns Integer value of configuration - */ - int GetInt(int idx); - - /** - * @brief Returns the value of the given key as an integer - * @details Uses linear search to find and access the value, as opposed to direct access with an index - * @param key Key associated with desired value - * @param deflt Default value of configuration - * @returns Integer value of configuration - */ - int GetInt(const char* key); - - /** - * @brief Clears key-value table - */ - void ClearKeyVals(); - - /** - * @brief Gives a detailed list of every added key and their value, and dumps it into the logging system - * @param log_level Determines the log priority level to print at (e.g. LOG_INFO, LOG_VERBOSE + 2) - */ - virtual void DumpToLog(int log_level); +class Config { + private: + int conf_errno; /** Stores any errors that happen during initialization */ + char path[CONF_MEMBER_LEN]; /** File Path */ + CONF_Entry pairs[CONF_PAIR_LIMIT]; /** Stored pairs */ + uint8_t key_count; /** Length of key-value table*/ + + /** + * @brief Parses file according to YAML standards (more or less) + * @param fd File descriptor of config file + * @returns 0 on success, -1 on failure + */ + int ParseYaml(int fd); + + /** + * @brief Linearly searches through keys table and returns the index of the + * key + * @details Each entry is offset CONF_KEY_LEN from one another + * @returns index on success, -1 on failure + */ + int GetKeyIndex(const char *key); + + /** + * @brief Helper function or handling an error during GetBool + * @param idx Index of config entry + * @returns Default bool value + */ + bool fail_get_bool(int idx); + + protected: + /** + * @brief Overrides a value in the key-value table at the given index + * @param key_idx index of Key-Value pair to override + * @param val Value to override pair with + * @returns 0 on success, -1 on failure + */ + int OverrideValue(uint8_t key_idx, const char *val); + + /** + * @brief Overrides a value in the key-value table at the given index + * @param key_idx index of Key-Value pair to override + * @param val Value to override pair with + * @returns 0 on success, -1 on failure + */ + int OverrideValue(uint8_t key_idx, bool val); + + public: + Config(); + virtual ~Config(); + + /** + * @brief Returns the path of the active config file + * @returns const pointer to the path member on success, NULL on failure + */ + const char *GetFilePath(); + + /** + * @brief Sets the path of the active config file + * @param path Path to set + * @returns 0 on success, -1 on failure + */ + int SetFilePath(const char *file_path); + + /** + * @brief Parses the selected config file + * @details opens the predesignated path, parses it, then closes; YAML is used + * as the format + * @returns 0 on success, -1 on failure + */ + int ParseConfig(); + + /** + * @brief Appends a key to the list of keys + * @param key Key to add + * @param deflt Default value of key; Will remain the value in the case of + * missing key/error + * @param type Data type of the key's value + * @returns -1 on failure, the index of the new key-value pair on success + */ + int AddKey(const char *key, const char *deflt, CONF_Data_Type type); + + /** + * @brief Appends a key to the list of keys + * @details Assumes value is a string + * @param key Key to add + * @param deflt Default value of configuration; (Named to avoid keyword + * conflict) + * @returns -1 on failure, key index on success + */ + int AddKey(const char *key, const char *deflt); + + /** + * @brief Appends a key to the list of keys + * @details Assumes value is a boolean + * @param key Key to add + * @param deflt Default value of configuration; (Named to avoid keyword + * conflict) + * @returns -1 on failure, key index on success + */ + int AddKey(const char *key, bool deflt); + + /** + * @brief Appends a key to the list of keys + * @details Assumes value is a integer + * @param key Key to add + * @param deflt Default value of configuration; (Named to avoid keyword + * conflict) + * @returns -1 on failure, key index on success + */ + int AddKey(const char *key, int deflt); + + /** + * @brief Returns a const char buffer containing the value associated with the + * given key index + * @details Uses index to directly access string; Faster than linear search + * overload + * @param idx Index of value's key + * @returns const char pointer to string on success, NULL on failure + */ + const char *GetVal(uint8_t idx); + + /** + * @brief Copies the associated value of a given key to the destination + * character pointer + * @details Searches through key list to find value + * @param key Key associated with value + * @returns const char pointer to string on success, NULL on failure + */ + const char *GetVal(const char *key); + + /** + * @brief Returns the value associated with the given index as a bool + * @details Uses index to directly access value, rather than linear search + * @param idx Index of value in key-value table + * @param deflt Default value of configuration + * @returns Boolean value of configuration + */ + bool GetBool(int idx); + + /** + * @brief Returns the value of the given key as a bool + * @details Uses linear search to find and access the value, as opposed to + * direct access with an index + * @param key Key associated with desired value + * @param deflt Default value of configuration + * @returns Boolean value of configuration + */ + bool GetBool(const char *key); + + /** + * @brief Returns the value associated with the given index as an integer + * @details Uses index to directly access value, rather than linear search + * @param idx Index of value in key-value table + * @param deflt Default value of configuration + * @returns Integer value of configuration + */ + int GetInt(int idx); + + /** + * @brief Returns the value of the given key as an integer + * @details Uses linear search to find and access the value, as opposed to + * direct access with an index + * @param key Key associated with desired value + * @param deflt Default value of configuration + * @returns Integer value of configuration + */ + int GetInt(const char *key); + + /** + * @brief Clears key-value table + */ + void ClearKeyVals(); + + /** + * @brief Gives a detailed list of every added key and their value, and dumps + * it into the logging system + * @param log_level Determines the log priority level to print at (e.g. + * LOG_INFO, LOG_VERBOSE + 2) + */ + virtual void DumpToLog(int log_level); }; - diff --git a/src/common/data/list.h b/src/common/data/list.h index ae824f7..e069fc2 100644 --- a/src/common/data/list.h +++ b/src/common/data/list.h @@ -6,6 +6,8 @@ * @param node Pointer to node * @param obj_type Type of desired structure * @param node_name Name of the node member within the parent structure - * @returns Pointer to parent object (type obj_type*) on success, NULL on failure -*/ -#define DATA_LIST_GET_OBJ(node, obj_type, node_name) ((obj_type*)(((uint8_t*) node) - offsetof(obj_type, node_name))) \ No newline at end of file + * @returns Pointer to parent object (type obj_type*) on success, NULL on + * failure + */ +#define DATA_LIST_GET_OBJ(node, obj_type, node_name) \ + ((obj_type *)(((uint8_t *)node) - offsetof(obj_type, node_name))) diff --git a/src/common/data/s_list.c b/src/common/data/s_list.c index 7b42298..deb1979 100644 --- a/src/common/data/s_list.c +++ b/src/common/data/s_list.c @@ -9,120 +9,110 @@ #define LOG_CONSOLE_THRESHOLD_THIS LOG_VERBOSE + 2 #define LOG_FILE_THRESHOLD_THIS LOG_VERBOSE + 2 -int8_t DATA_S_List_Node_init (S_List_Node *node) -{ - if (!node) STD_FAIL; - memset(node, 0, sizeof(S_List_Node)); - return 0; +int8_t DATA_S_List_Node_init(S_List_Node *node) { + if (!node) STD_FAIL; + memset(node, 0, sizeof(S_List_Node)); + return 0; } -int8_t DATA_S_List_init (S_List *list) -{ - if (!list) STD_FAIL; - memset(list, 0, sizeof(S_List)); - return 0; +int8_t DATA_S_List_init(S_List *list) { + if (!list) STD_FAIL; + memset(list, 0, sizeof(S_List)); + return 0; } -int8_t DATA_S_List_deinit (S_List *list) -{ - if (!list) STD_FAIL; - while (list->len > 0) - { - // Pop head; preserve list in case of error - S_List_Node *iter = DATA_S_List_pop(list); - if (!iter && list->len > 0) STD_FAIL; - - // Reinit purged node - DATA_S_List_Node_init (iter); - } - - if (list->head) STD_FAIL - if (list->tail) STD_FAIL - if (list->len) STD_FAIL; - return 0; +int8_t DATA_S_List_deinit(S_List *list) { + if (!list) STD_FAIL; + while (list->len > 0) { + // Pop head; preserve list in case of error + S_List_Node *iter = DATA_S_List_pop(list); + if (!iter && list->len > 0) STD_FAIL; + + // Reinit purged node + DATA_S_List_Node_init(iter); + } + + if (list->head) STD_FAIL + if (list->tail) STD_FAIL + if (list->len) STD_FAIL; + return 0; } -int8_t DATA_S_List_append (S_List *list, S_List_Node *node) -{ - if (!list) STD_FAIL; - if (node->next) STD_FAIL; +int8_t DATA_S_List_append(S_List *list, S_List_Node *node) { + if (!list) STD_FAIL; + if (node->next) STD_FAIL; - if (list->len == 0) list->head = node; - else list->tail->next = node; + if (list->len == 0) + list->head = node; + else + list->tail->next = node; - list->tail = node; - list->len++; - return 0; + list->tail = node; + list->len++; + return 0; } -int8_t DATA_S_List_append_list(S_List *parent, S_List *child) -{ - if (!parent) STD_FAIL; - if (!child) STD_FAIL; +int8_t DATA_S_List_append_list(S_List *parent, S_List *child) { + if (!parent) STD_FAIL; + if (!child) STD_FAIL; - if (0 == child->len) - { - return 0; - } + if (0 == child->len) { + return 0; + } - if (0 == parent->len) - { - *parent = *child; - } + if (0 == parent->len) { + *parent = *child; + } - else - { - parent->tail->next = child->head; - parent->tail = child->tail; - parent->len += child->len; - } + else { + parent->tail->next = child->head; + parent->tail = child->tail; + parent->len += child->len; + } - DATA_S_List_init(child); - return 0; + DATA_S_List_init(child); + return 0; } -int8_t DATA_S_List_insert (S_List *list, S_List_Node *node, uint16_t index) -{ - if (!list || !node) STD_FAIL; - if (index > list->len) STD_FAIL; - if (index == list->len) - { - int8_t ret = DATA_S_List_append (list, node); - if (ret == -1) STD_FAIL - else return 0; - } - - // Guranteed to not be last - S_List_Node **link = &list->head; - S_List_Node *n_iter = list->head; - for(uint16_t c_iter = 0; c_iter < index && n_iter; c_iter++) - { - link = &n_iter->next; - n_iter = n_iter->next; - } - - if (!link) STD_FAIL; - node->next = n_iter; - *link = node; - return 0; +int8_t DATA_S_List_insert(S_List *list, S_List_Node *node, uint16_t index) { + if (!list || !node) STD_FAIL; + if (index > list->len) STD_FAIL; + if (index == list->len) { + int8_t ret = DATA_S_List_append(list, node); + if (ret == -1) + STD_FAIL + else + return 0; + } + + // Guranteed to not be last + S_List_Node **link = &list->head; + S_List_Node *n_iter = list->head; + for (uint16_t c_iter = 0; c_iter < index && n_iter; c_iter++) { + link = &n_iter->next; + n_iter = n_iter->next; + } + + if (!link) STD_FAIL; + node->next = n_iter; + *link = node; + return 0; } -int8_t DATA_S_List_prepend (S_List *list, S_List_Node *node) -{ - if (!list) STD_FAIL; - if (node->next) STD_FAIL; - if (DATA_S_List_insert(list, node, 0) == -1) STD_FAIL; - return 0; +int8_t DATA_S_List_prepend(S_List *list, S_List_Node *node) { + if (!list) STD_FAIL; + if (node->next) STD_FAIL; + if (DATA_S_List_insert(list, node, 0) == -1) STD_FAIL; + return 0; } -S_List_Node *DATA_S_List_pop (S_List *list) -{ - if (!list || list->len == 0) return NULL; +S_List_Node *DATA_S_List_pop(S_List *list) { + if (!list || list->len == 0) return NULL; - S_List_Node *node = list->head; - list->head = list->head->next; - list->len--; - if (list->len == 0) list->tail = list->head = NULL; - DATA_S_List_Node_init(node); - return node; + S_List_Node *node = list->head; + list->head = list->head->next; + list->len--; + if (list->len == 0) list->tail = list->head = NULL; + DATA_S_List_Node_init(node); + return node; } diff --git a/src/common/data/s_list.h b/src/common/data/s_list.h index dda15b9..579081f 100644 --- a/src/common/data/s_list.h +++ b/src/common/data/s_list.h @@ -1,12 +1,15 @@ /** * Singly Linked List - * - * The operation of this module is a little different than the standard implementation of an SLL. - * Typically, each node in a list stores two things: the next node in the list, and a piece of data - * For this SLL, a node simply stores the pointer of the next node. The node is a member within the object it tracks - * To get the pointer to a node's respective object, offset arithmatic is used (DATA_LIST_GET_OBJ in list.h) - * Doing it this way allows an object to be tracked by multiple lists, and allows the list to be completely agnostic to the data/type it tracks -*/ + * + * The operation of this module is a little different than the standard + * implementation of an SLL. Typically, each node in a list stores two things: + * the next node in the list, and a piece of data For this SLL, a node simply + * stores the pointer of the next node. The node is a member within the object + * it tracks To get the pointer to a node's respective object, offset arithmatic + * is used (DATA_LIST_GET_OBJ in list.h) Doing it this way allows an object to + * be tracked by multiple lists, and allows the list to be completely agnostic + * to the data/type it tracks + */ #pragma once @@ -15,54 +18,53 @@ #include "data/list.h" /** Singly Linked List Node */ -typedef struct _s_list_node -{ - struct _s_list_node *next; /** Pointer to next node */ +typedef struct _s_list_node { + struct _s_list_node *next; /** Pointer to next node */ } S_List_Node; /** Singly Linked List */ -typedef struct _s_list -{ - S_List_Node *head; /** Pointer to head of list */ - S_List_Node *tail; /** Pointer to tail of list */ - uint32_t len; /** Length of list */ +typedef struct _s_list { + S_List_Node *head; /** Pointer to head of list */ + S_List_Node *tail; /** Pointer to tail of list */ + uint32_t len; /** Length of list */ } S_List; /** * @brief Initializes a Node for a Singly Linked List * @param node Node to initialize * @returns 0 on success, -1 on failure -*/ -int8_t DATA_S_List_Node_init (S_List_Node *node); + */ +int8_t DATA_S_List_Node_init(S_List_Node *node); /** * @brief Initializes a Singly Linked List * @param list List to initialize * @returns 0 on success, -1 on failure -*/ -int8_t DATA_S_List_init (S_List *list); + */ +int8_t DATA_S_List_init(S_List *list); /** * @brief Denitializes a Singly Linked List * @param list List to deinitialize * @returns 0 on success, -1 on failure -*/ -int8_t DATA_S_List_deinit (S_List *list); + */ +int8_t DATA_S_List_deinit(S_List *list); /** * @brief Append node to the end of a Singly Linked List * @param node Node to append * @returns 0 on success, -1 on failure -*/ -int8_t DATA_S_List_append (S_List *list, S_List_Node *node); + */ +int8_t DATA_S_List_append(S_List *list, S_List_Node *node); /** - * @brief Appends the first element of the child list to the last element of the parent list + * @brief Appends the first element of the child list to the last element of the + * parent list * @details Reinitalizes child list * @param parent Parent S_List to append elements onto * @param child Child S_List to move elements from * @returns 0 on success, -1 on failure -*/ + */ int8_t DATA_S_List_append_list(S_List *parent, S_List *child); /** @@ -70,19 +72,18 @@ int8_t DATA_S_List_append_list(S_List *parent, S_List *child); * @param node Node to insert * @param index Index to insert node at * @returns 0 on success, -1 on failure -*/ -int8_t DATA_S_List_insert (S_List *list, S_List_Node *node, uint16_t index); + */ +int8_t DATA_S_List_insert(S_List *list, S_List_Node *node, uint16_t index); /** * @brief Prepends node to the beginning of a Singly Linked List * @param node Node to prepend * @returns 0 on success, -1 on failure -*/ -int8_t DATA_S_List_prepend (S_List *list, S_List_Node *node); + */ +int8_t DATA_S_List_prepend(S_List *list, S_List_Node *node); /** * @brief Pops node from the beginning of a Singly Linked List * @returns Pointer to node from top of list on success, NULL on failure -*/ -S_List_Node * DATA_S_List_pop (S_List *list); - + */ +S_List_Node *DATA_S_List_pop(S_List *list); diff --git a/src/common/data/s_list_test.cpp b/src/common/data/s_list_test.cpp index e6396ec..f16e2b2 100644 --- a/src/common/data/s_list_test.cpp +++ b/src/common/data/s_list_test.cpp @@ -1,258 +1,227 @@ -#include "CppUTest/TestHarness.h" #include "data/s_list.h" -#include "log/log.h" + #include -TEST_GROUP(base) -{ -}; +#include "CppUTest/TestHarness.h" +#include "log/log.h" -TEST(base, node_init) -{ - S_List_Node node; - node.next = (S_List_Node*) -5; +TEST_GROUP(base){}; - DATA_S_List_Node_init(&node); +TEST(base, node_init) { + S_List_Node node; + node.next = (S_List_Node *)-5; - POINTERS_EQUAL(NULL, node.next); + DATA_S_List_Node_init(&node); + + POINTERS_EQUAL(NULL, node.next); } -TEST(base, list_init) -{ - S_List list; - list.head = (S_List_Node *) -1; - list.tail = (S_List_Node *) -2; - list.len = 45; +TEST(base, list_init) { + S_List list; + list.head = (S_List_Node *)-1; + list.tail = (S_List_Node *)-2; + list.len = 45; - DATA_S_List_init(&list); + DATA_S_List_init(&list); - POINTERS_EQUAL(NULL, list.head); - POINTERS_EQUAL(NULL, list.tail); - CHECK_EQUAL(0, list.len); + POINTERS_EQUAL(NULL, list.head); + POINTERS_EQUAL(NULL, list.tail); + CHECK_EQUAL(0, list.len); } -TEST_GROUP(nominal) -{ - S_List list; - S_List_Node node; +TEST_GROUP(nominal) { + S_List list; + S_List_Node node; - void setup() - { - DATA_S_List_init(&list); - CHECK_EQUAL(0, DATA_S_List_Node_init(&node)); - } + void setup() { + DATA_S_List_init(&list); + CHECK_EQUAL(0, DATA_S_List_Node_init(&node)); + } - void teardown() - { - DATA_S_List_deinit(&list); - } + void teardown() { DATA_S_List_deinit(&list); } }; -TEST(nominal, append_onto_empty) -{ - POINTERS_EQUAL(NULL, list.head); - POINTERS_EQUAL(NULL, list.tail); - CHECK_EQUAL (0, list.len); +TEST(nominal, append_onto_empty) { + POINTERS_EQUAL(NULL, list.head); + POINTERS_EQUAL(NULL, list.tail); + CHECK_EQUAL(0, list.len); - DATA_S_List_append(&list, &node); + DATA_S_List_append(&list, &node); - POINTERS_EQUAL(NULL, node.next); - POINTERS_EQUAL(&node, list.head); - POINTERS_EQUAL(&node, list.tail); - CHECK_EQUAL (1, list.len); + POINTERS_EQUAL(NULL, node.next); + POINTERS_EQUAL(&node, list.head); + POINTERS_EQUAL(&node, list.tail); + CHECK_EQUAL(1, list.len); } -TEST(nominal, insert_into_empty) -{ - POINTERS_EQUAL(NULL, list.head); - POINTERS_EQUAL(NULL, list.tail); - CHECK_EQUAL (0, list.len); +TEST(nominal, insert_into_empty) { + POINTERS_EQUAL(NULL, list.head); + POINTERS_EQUAL(NULL, list.tail); + CHECK_EQUAL(0, list.len); - DATA_S_List_insert(&list, &node, 0); + DATA_S_List_insert(&list, &node, 0); - POINTERS_EQUAL(NULL, node.next); - POINTERS_EQUAL(&node, list.head); - POINTERS_EQUAL(&node, list.tail); - CHECK_EQUAL (1, list.len); + POINTERS_EQUAL(NULL, node.next); + POINTERS_EQUAL(&node, list.head); + POINTERS_EQUAL(&node, list.tail); + CHECK_EQUAL(1, list.len); } -TEST(nominal, prepend_onto_empty) -{ - POINTERS_EQUAL(NULL, list.head); - POINTERS_EQUAL(NULL, list.tail); - CHECK_EQUAL (0, list.len); +TEST(nominal, prepend_onto_empty) { + POINTERS_EQUAL(NULL, list.head); + POINTERS_EQUAL(NULL, list.tail); + CHECK_EQUAL(0, list.len); - CHECK_EQUAL(0, DATA_S_List_prepend(&list, &node)); + CHECK_EQUAL(0, DATA_S_List_prepend(&list, &node)); - POINTERS_EQUAL(NULL, node.next); - POINTERS_EQUAL(&node, list.head); - POINTERS_EQUAL(&node, list.tail); - CHECK_EQUAL (1, list.len); + POINTERS_EQUAL(NULL, node.next); + POINTERS_EQUAL(&node, list.head); + POINTERS_EQUAL(&node, list.tail); + CHECK_EQUAL(1, list.len); } -TEST(nominal, pop_last) -{ - DATA_S_List_append(&list, &node); +TEST(nominal, pop_last) { + DATA_S_List_append(&list, &node); - POINTERS_EQUAL(NULL, node.next); - POINTERS_EQUAL(&node, list.head); - POINTERS_EQUAL(&node, list.tail); - CHECK_EQUAL (1, list.len); + POINTERS_EQUAL(NULL, node.next); + POINTERS_EQUAL(&node, list.head); + POINTERS_EQUAL(&node, list.tail); + CHECK_EQUAL(1, list.len); - POINTERS_EQUAL(&node, DATA_S_List_pop(&list)); + POINTERS_EQUAL(&node, DATA_S_List_pop(&list)); - POINTERS_EQUAL(NULL, list.head); - POINTERS_EQUAL(NULL, list.tail); - CHECK_EQUAL (0, list.len); + POINTERS_EQUAL(NULL, list.head); + POINTERS_EQUAL(NULL, list.tail); + CHECK_EQUAL(0, list.len); } +TEST_GROUP(nominal_large) { + S_List list; -TEST_GROUP(nominal_large) -{ - S_List list; - - typedef struct _test_struct - { - uint8_t id; - uint8_t dummy[15]; - S_List_Node node; - } Test_Struct; - - Test_Struct structs[5]; - const uint8_t structs_len = 5; - - void setup() - { - LOG_init(); - DATA_S_List_init(&list); - for (uint8_t n_iter = 0; n_iter < structs_len; n_iter++) - { - structs[n_iter].id = n_iter; - memset(&structs[n_iter].dummy[0], 0, sizeof(structs[n_iter].dummy)); - CHECK_EQUAL(0, DATA_S_List_Node_init(&structs[n_iter].node)); - } - } + typedef struct _test_struct { + uint8_t id; + uint8_t dummy[15]; + S_List_Node node; + } Test_Struct; + + Test_Struct structs[5]; + const uint8_t structs_len = 5; - void teardown() - { - DATA_S_List_deinit(&list); - LOG_destory(); + void setup() { + LOG_init(); + DATA_S_List_init(&list); + for (uint8_t n_iter = 0; n_iter < structs_len; n_iter++) { + structs[n_iter].id = n_iter; + memset(&structs[n_iter].dummy[0], 0, sizeof(structs[n_iter].dummy)); + CHECK_EQUAL(0, DATA_S_List_Node_init(&structs[n_iter].node)); } + } + + void teardown() { + DATA_S_List_deinit(&list); + LOG_destory(); + } }; -TEST(nominal_large, append_and_pop) -{ - for (uint8_t n_iter = 0; n_iter < structs_len; n_iter++) - { - CHECK_EQUAL(n_iter, list.len); - CHECK_EQUAL(0, DATA_S_List_append(&list, &structs[n_iter].node)); - } +TEST(nominal_large, append_and_pop) { + for (uint8_t n_iter = 0; n_iter < structs_len; n_iter++) { + CHECK_EQUAL(n_iter, list.len); + CHECK_EQUAL(0, DATA_S_List_append(&list, &structs[n_iter].node)); + } - CHECK_EQUAL(structs_len, list.len); + CHECK_EQUAL(structs_len, list.len); - S_List_Node *iter = list.head; - uint8_t n_iter = 0; - for (; n_iter < structs_len - 1; n_iter++) - { - POINTERS_EQUAL(&structs[n_iter].node, iter); - POINTERS_EQUAL(&structs[n_iter+1].node, iter->next); - iter = iter->next; - } + S_List_Node *iter = list.head; + uint8_t n_iter = 0; + for (; n_iter < structs_len - 1; n_iter++) { POINTERS_EQUAL(&structs[n_iter].node, iter); - POINTERS_EQUAL(NULL, iter->next); - - iter = list.head; - n_iter = 0; - S_List_Node *pop; - for(; n_iter < structs_len; n_iter++) - { - POINTERS_EQUAL(list.head, iter); - S_List_Node *next = iter->next; - pop = DATA_S_List_pop(&list); - POINTERS_EQUAL(iter, pop); - iter = next; - } - POINTERS_EQUAL(NULL, iter); - POINTERS_EQUAL(NULL, DATA_S_List_pop(&list)); + POINTERS_EQUAL(&structs[n_iter + 1].node, iter->next); + iter = iter->next; + } + POINTERS_EQUAL(&structs[n_iter].node, iter); + POINTERS_EQUAL(NULL, iter->next); + + iter = list.head; + n_iter = 0; + S_List_Node *pop; + for (; n_iter < structs_len; n_iter++) { + POINTERS_EQUAL(list.head, iter); + S_List_Node *next = iter->next; + pop = DATA_S_List_pop(&list); + POINTERS_EQUAL(iter, pop); + iter = next; + } + POINTERS_EQUAL(NULL, iter); + POINTERS_EQUAL(NULL, DATA_S_List_pop(&list)); } - -TEST(nominal_large, append_and_insert) -{ - //Append 0,1,3,4 - for (uint8_t n_iter = 0; n_iter < 2; n_iter++) - { - CHECK_EQUAL(n_iter, list.len); - CHECK_EQUAL(0, DATA_S_List_append(&list, &structs[n_iter].node)); - POINTERS_EQUAL(&structs[n_iter], DATA_LIST_GET_OBJ(list.tail, Test_Struct, node)); - } - for (uint8_t n_iter = 3; n_iter < structs_len; n_iter++) - { - CHECK_EQUAL(n_iter - 1, list.len); - CHECK_EQUAL(0, DATA_S_List_append(&list, &structs[n_iter].node)); - POINTERS_EQUAL(&structs[n_iter], DATA_LIST_GET_OBJ(list.tail, Test_Struct, node)); - } - - // Confirm order - S_List_Node *iter = list.head; - for (uint8_t n_iter = 0; n_iter < 2; n_iter++) - { - Test_Struct *ts = DATA_LIST_GET_OBJ(iter, Test_Struct, node); - POINTERS_EQUAL(n_iter, ts->id); - iter = iter->next; - } - for (uint8_t n_iter = 3; n_iter < structs_len; n_iter++) - { - Test_Struct *ts = DATA_LIST_GET_OBJ(iter, Test_Struct, node); - POINTERS_EQUAL(n_iter, ts->id); - iter = iter->next; - } - - // Add 2 in the right spot - DATA_S_List_insert (&list, &structs[2].node, 2); - - // Confirm order - iter = list.head; - for (uint8_t n_iter = 0; n_iter < structs_len; n_iter++) - { - Test_Struct *ts = DATA_LIST_GET_OBJ(iter, Test_Struct, node); - POINTERS_EQUAL(n_iter, ts->id); - iter = iter->next; - } +TEST(nominal_large, append_and_insert) { + // Append 0,1,3,4 + for (uint8_t n_iter = 0; n_iter < 2; n_iter++) { + CHECK_EQUAL(n_iter, list.len); + CHECK_EQUAL(0, DATA_S_List_append(&list, &structs[n_iter].node)); + POINTERS_EQUAL(&structs[n_iter], + DATA_LIST_GET_OBJ(list.tail, Test_Struct, node)); + } + for (uint8_t n_iter = 3; n_iter < structs_len; n_iter++) { + CHECK_EQUAL(n_iter - 1, list.len); + CHECK_EQUAL(0, DATA_S_List_append(&list, &structs[n_iter].node)); + POINTERS_EQUAL(&structs[n_iter], + DATA_LIST_GET_OBJ(list.tail, Test_Struct, node)); + } + + // Confirm order + S_List_Node *iter = list.head; + for (uint8_t n_iter = 0; n_iter < 2; n_iter++) { + Test_Struct *ts = DATA_LIST_GET_OBJ(iter, Test_Struct, node); + POINTERS_EQUAL(n_iter, ts->id); + iter = iter->next; + } + for (uint8_t n_iter = 3; n_iter < structs_len; n_iter++) { + Test_Struct *ts = DATA_LIST_GET_OBJ(iter, Test_Struct, node); + POINTERS_EQUAL(n_iter, ts->id); + iter = iter->next; + } + + // Add 2 in the right spot + DATA_S_List_insert(&list, &structs[2].node, 2); + + // Confirm order + iter = list.head; + for (uint8_t n_iter = 0; n_iter < structs_len; n_iter++) { + Test_Struct *ts = DATA_LIST_GET_OBJ(iter, Test_Struct, node); + POINTERS_EQUAL(n_iter, ts->id); + iter = iter->next; + } } -TEST(nominal_large, append_and_prepend) -{ - //Append 1,2,3,4 - for (uint8_t n_iter = 1; n_iter < structs_len; n_iter++) - { - CHECK_EQUAL(n_iter - 1, list.len); - CHECK_EQUAL(0, DATA_S_List_append(&list, &structs[n_iter].node)); - POINTERS_EQUAL(&structs[n_iter], DATA_LIST_GET_OBJ(list.tail, Test_Struct, node)); - } - - // Confirm order - S_List_Node *iter = list.head; - for (uint8_t n_iter = 1; n_iter < structs_len; n_iter++) - { - Test_Struct *ts = DATA_LIST_GET_OBJ(iter, Test_Struct, node); - POINTERS_EQUAL(n_iter, ts->id); - iter = iter->next; - } - - // Add 2 in the right spot - DATA_S_List_prepend (&list, &structs[0].node); - - // Confirm order - iter = list.head; - for (uint8_t n_iter = 0; n_iter < structs_len; n_iter++) - { - Test_Struct *ts = DATA_LIST_GET_OBJ(iter, Test_Struct, node); - POINTERS_EQUAL(n_iter, ts->id); - iter = iter->next; - } +TEST(nominal_large, append_and_prepend) { + // Append 1,2,3,4 + for (uint8_t n_iter = 1; n_iter < structs_len; n_iter++) { + CHECK_EQUAL(n_iter - 1, list.len); + CHECK_EQUAL(0, DATA_S_List_append(&list, &structs[n_iter].node)); + POINTERS_EQUAL(&structs[n_iter], + DATA_LIST_GET_OBJ(list.tail, Test_Struct, node)); + } + + // Confirm order + S_List_Node *iter = list.head; + for (uint8_t n_iter = 1; n_iter < structs_len; n_iter++) { + Test_Struct *ts = DATA_LIST_GET_OBJ(iter, Test_Struct, node); + POINTERS_EQUAL(n_iter, ts->id); + iter = iter->next; + } + + // Add 2 in the right spot + DATA_S_List_prepend(&list, &structs[0].node); + + // Confirm order + iter = list.head; + for (uint8_t n_iter = 0; n_iter < structs_len; n_iter++) { + Test_Struct *ts = DATA_LIST_GET_OBJ(iter, Test_Struct, node); + POINTERS_EQUAL(n_iter, ts->id); + iter = iter->next; + } } -TEST_GROUP(bad) -{ -}; \ No newline at end of file +TEST_GROUP(bad){}; \ No newline at end of file diff --git a/src/common/log/log.c b/src/common/log/log.c index 8a770e8..2e24937 100644 --- a/src/common/log/log.c +++ b/src/common/log/log.c @@ -1,16 +1,17 @@ -#include +#include "log/log.h" + +#include +#include #include -#include -#include #include -#include -#include #include +#include +#include +#include +#include +#include #include -#include -#include -#include "log/log.h" #include "log/log_private.h" #include "util/comm.h" #include "util/timestamp.h" @@ -18,288 +19,261 @@ #define LOG_CLOCK CLOCK_REALTIME #define LOG_TS_LEN (UTIL_TIMESTAMP_LEN + UTIL_TS_MSEC_LEN + 1) -#define LOG_CONSOLE_THRESHOLD_THIS LOG_THRESHOLD_MAX -#define LOG_FILE_THRESHOLD_THIS LOG_THRESHOLD_MAX +#define LOG_CONSOLE_THRESHOLD_THIS LOG_THRESHOLD_MAX +#define LOG_FILE_THRESHOLD_THIS LOG_THRESHOLD_MAX Log the_log; -static int8_t LOG_timestamp(char* dst_str) -{ - struct timespec ts; - int ret = clock_gettime(LOG_CLOCK, &ts); - char* str_iter = dst_str; - - ret = UTIL_time_iso8601_timestamp_UTC(str_iter, ts.tv_sec); - if (ret == -1) return -1; // Can't log error: recursive call - str_iter += ret; - - ret = UTIL_time_msec_timestamp(str_iter, ts.tv_nsec / 1000); - if (ret == -1) return -1; // Can't log error: recursive call - str_iter += ret; - str_iter += sprintf(str_iter, "Z"); - return str_iter - dst_str; +static int8_t LOG_timestamp(char *dst_str) { + struct timespec ts; + int ret = clock_gettime(LOG_CLOCK, &ts); + char *str_iter = dst_str; + + ret = UTIL_time_iso8601_timestamp_UTC(str_iter, ts.tv_sec); + if (ret == -1) return -1; // Can't log error: recursive call + str_iter += ret; + + ret = UTIL_time_msec_timestamp(str_iter, ts.tv_nsec / 1000); + if (ret == -1) return -1; // Can't log error: recursive call + str_iter += ret; + str_iter += sprintf(str_iter, "Z"); + return str_iter - dst_str; } -static uint8_t get_level_name(char* dst, uint8_t level, bool color) -{ - if (level > 9 + (uint8_t) LOG_VERBOSE) return -1; +static uint8_t get_level_name(char *dst, uint8_t level, bool color) { + if (level > 9 + (uint8_t)LOG_VERBOSE) return -1; - int8_t vlev = -1; - uint8_t offset = 0; + int8_t vlev = -1; + uint8_t offset = 0; - if (level >= (uint8_t) LOG_VERBOSE) - { - vlev = level - (uint8_t) LOG_VERBOSE; - level = LOG_VERBOSE; - } + if (level >= (uint8_t)LOG_VERBOSE) { + vlev = level - (uint8_t)LOG_VERBOSE; + level = LOG_VERBOSE; + } - if (color) - offset += sprintf(dst + offset, "%s", _LOG_level_color[level]); + if (color) offset += sprintf(dst + offset, "%s", _LOG_level_color[level]); - if (vlev != -1) - offset += sprintf(dst + offset, "%s:%d ", log_level_names[level], vlev); - else - offset += sprintf(dst + offset, "%-9s ", log_level_names[level]); // Left justified, 13 for "LOG_VERBOSE:0" - - if (color) - offset += sprintf(dst + offset, "%s", COLOR_RESET); + if (vlev != -1) + offset += sprintf(dst + offset, "%s:%d ", log_level_names[level], vlev); + else + offset += sprintf( + dst + offset, "%-9s ", + log_level_names[level]); // Left justified, 13 for "LOG_VERBOSE:0" + + if (color) offset += sprintf(dst + offset, "%s", COLOR_RESET); - return offset; + return offset; } -static uint16_t format_log_entry(char* dst, LOG_Buffer *buf, bool use_color) -{ - uint16_t msg_iter = 0; +static uint16_t format_log_entry(char *dst, LOG_Buffer *buf, bool use_color) { + uint16_t msg_iter = 0; - // Timestamp - char ts[LOG_TS_LEN]; - LOG_timestamp(&ts[0]); - msg_iter += sprintf(dst + msg_iter, "[%s] ", ts); + // Timestamp + char ts[LOG_TS_LEN]; + LOG_timestamp(&ts[0]); + msg_iter += sprintf(dst + msg_iter, "[%s] ", ts); - // Level - msg_iter += get_level_name(dst + msg_iter, buf->level, use_color); + // Level + msg_iter += get_level_name(dst + msg_iter, buf->level, use_color); - // Message - msg_iter += sprintf(dst + msg_iter, "%s", buf->msg); - msg_iter += sprintf(dst + msg_iter, "\n"); - return msg_iter; + // Message + msg_iter += sprintf(dst + msg_iter, "%s", buf->msg); + msg_iter += sprintf(dst + msg_iter, "\n"); + return msg_iter; } -void LOG_thread_print(LOG_Buffer *buf) -{ - char msg[1024]; - - // Console out - if (buf->flags & (1 << LOG_BUFFER_FLAG_OUT_CONSOLE)) - { - format_log_entry(&msg[0], buf, LOG_USE_COLOR); - #if LOG_USE_STDERR - if (buf->level <= LOG_ERROR) - fprintf(stderr, "%s", msg); - else printf("%s", msg); - #else - printf("%s", msg); - #endif - } +void LOG_thread_print(LOG_Buffer *buf) { + char msg[1024]; - // File out - if (-1 != the_log.fd && buf->flags & (1 << LOG_BUFFER_FLAG_OUT_FILE)) - { - uint16_t len = format_log_entry(&msg[0], buf, false) + 1; - write(the_log.fd, &msg[0], len-1); - } + // Console out + if (buf->flags & (1 << LOG_BUFFER_FLAG_OUT_CONSOLE)) { + format_log_entry(&msg[0], buf, LOG_USE_COLOR); +#if LOG_USE_STDERR + if (buf->level <= LOG_ERROR) + fprintf(stderr, "%s", msg); + else + printf("%s", msg); +#else + printf("%s", msg); +#endif + } + + // File out + if (-1 != the_log.fd && buf->flags & (1 << LOG_BUFFER_FLAG_OUT_FILE)) { + uint16_t len = format_log_entry(&msg[0], buf, false) + 1; + write(the_log.fd, &msg[0], len - 1); + } } -static int8_t LOG_Buffer_init(LOG_Buffer *buf) -{ - if (!buf) return -1; - memset(buf, 0, sizeof(LOG_Buffer)); - DATA_S_List_Node_init(&buf->node); +static int8_t LOG_Buffer_init(LOG_Buffer *buf) { + if (!buf) return -1; + memset(buf, 0, sizeof(LOG_Buffer)); + DATA_S_List_Node_init(&buf->node); - return 0; + return 0; } -void LOG_thread_poll() -{ - pthread_mutex_lock (&the_log.wr_lock); - S_List_Node *node = DATA_S_List_pop(&the_log.wr_queue); - pthread_mutex_unlock (&the_log.wr_lock); +void LOG_thread_poll() { + pthread_mutex_lock(&the_log.wr_lock); + S_List_Node *node = DATA_S_List_pop(&the_log.wr_queue); + pthread_mutex_unlock(&the_log.wr_lock); - if (!node) return; - LOG_Buffer *buf = DATA_LIST_GET_OBJ(node, LOG_Buffer, node); - LOG_thread_print(buf); + if (!node) return; + LOG_Buffer *buf = DATA_LIST_GET_OBJ(node, LOG_Buffer, node); + LOG_thread_print(buf); - pthread_mutex_lock (&the_log.free_lock); - LOG_Buffer_init(buf); - DATA_S_List_append(&the_log.free_queue, &buf->node); - pthread_mutex_unlock (&the_log.free_lock); + pthread_mutex_lock(&the_log.free_lock); + LOG_Buffer_init(buf); + DATA_S_List_append(&the_log.free_queue, &buf->node); + pthread_mutex_unlock(&the_log.free_lock); } -static LOG_Buffer *get_buffer(Log *log) -{ - pthread_mutex_lock (&log->free_lock); - S_List_Node* node = DATA_S_List_pop(&log->free_queue); - pthread_mutex_unlock(&log->free_lock); +static LOG_Buffer *get_buffer(Log *log) { + pthread_mutex_lock(&log->free_lock); + S_List_Node *node = DATA_S_List_pop(&log->free_queue); + pthread_mutex_unlock(&log->free_lock); - if (!node) return NULL; - LOG_Buffer* buf = DATA_LIST_GET_OBJ(node, LOG_Buffer, node); - return buf; + if (!node) return NULL; + LOG_Buffer *buf = DATA_LIST_GET_OBJ(node, LOG_Buffer, node); + return buf; } -static int8_t push_buffer(Log *log, LOG_Buffer *buf) -{ - if (!log || !buf) return -1; - pthread_mutex_lock (&log->wr_lock); - DATA_S_List_append(&log->wr_queue, &buf->node); - pthread_mutex_unlock(&log->wr_lock); - return 0; +static int8_t push_buffer(Log *log, LOG_Buffer *buf) { + if (!log || !buf) return -1; + pthread_mutex_lock(&log->wr_lock); + DATA_S_List_append(&log->wr_queue, &buf->node); + pthread_mutex_unlock(&log->wr_lock); + return 0; } -int8_t LOG_print(const char* file, uint16_t line, int8_t console_threshold, int8_t file_threshold, int8_t level, const char* fmt, ...) -{ - // Check if message is important enough to print - uint8_t flags = 0; - if (level <= console_threshold) flags |= (1 << LOG_BUFFER_FLAG_OUT_CONSOLE); - if (level <= file_threshold) flags |= (1 << LOG_BUFFER_FLAG_OUT_FILE); - if (!flags) return 0; - - // Get timestamp - struct timespec ts; - int ret = clock_gettime(LOG_CLOCK, &ts); - if (ret == -1) return -1; - - // Get buffer - LOG_Buffer tmp; - LOG_Buffer *buf; - - if (the_log.config.en) - { - buf = get_buffer(&the_log); - if(!buf) - { - printf("LOG OUT OF RESOURCES\n"); - return -1; - } - } - else - { - LOG_Buffer_init(&tmp); - buf = &tmp; +int8_t LOG_print(const char *file, uint16_t line, int8_t console_threshold, + int8_t file_threshold, int8_t level, const char *fmt, ...) { + // Check if message is important enough to print + uint8_t flags = 0; + if (level <= console_threshold) flags |= (1 << LOG_BUFFER_FLAG_OUT_CONSOLE); + if (level <= file_threshold) flags |= (1 << LOG_BUFFER_FLAG_OUT_FILE); + if (!flags) return 0; + + // Get timestamp + struct timespec ts; + int ret = clock_gettime(LOG_CLOCK, &ts); + if (ret == -1) return -1; + + // Get buffer + LOG_Buffer tmp; + LOG_Buffer *buf; + + if (the_log.config.en) { + buf = get_buffer(&the_log); + if (!buf) { + printf("LOG OUT OF RESOURCES\n"); + return -1; } + } else { + LOG_Buffer_init(&tmp); + buf = &tmp; + } + + // Populate buffer + buf->timestamp = ts; + buf->level = level; + buf->flags = flags; + + va_list list; + va_start(list, fmt); + if (the_log.config.print_loc) { + buf->len += sprintf(&buf->msg[buf->len], "[%s : %4d]: ", file, line); + } + buf->len += vsprintf(&buf->msg[buf->len], fmt, list) + 1; + va_end(list); + + // Handle buffer + if (the_log.config.en) { + // If the log is enabled, put on write queue + ret = push_buffer(&the_log, buf); + if (ret == -1) return -1; + } else { + // If the log is disabled, print the buffer directly + LOG_thread_print(buf); + } - // Populate buffer - buf->timestamp = ts; - buf->level = level; - buf->flags = flags; + return 0; +} - va_list list; - va_start(list, fmt); - if (the_log.config.print_loc) - { - buf->len += sprintf(&buf->msg[buf->len], "[%s : %4d]: ", file, line); - } - buf->len += vsprintf(&buf->msg[buf->len], fmt, list) + 1; - va_end(list); - - // Handle buffer - if (the_log.config.en) - { - // If the log is enabled, put on write queue - ret = push_buffer(&the_log, buf); - if (ret == -1) return -1; - } - else - { - // If the log is disabled, print the buffer directly - LOG_thread_print(buf); +static void *LOG_run(void *) { + // TODO: add exit polling + while (1) { + if (0 == the_log.wr_queue.len) { + if (!the_log.config.en) break; + usleep(LOG_POLL_PERIOD_US); + continue; } + LOG_thread_poll(); + } - return 0; + return 0; } -static void *LOG_run(void*) -{ - // TODO: add exit polling - while(1) - { - if (0 == the_log.wr_queue.len) - { - if (!the_log.config.en) break; - usleep(LOG_POLL_PERIOD_US); - continue; - } - LOG_thread_poll(); - } +static int8_t init_log_lists(Log *log) { + if (!log) return -1; - return 0; -} + DATA_S_List_init(&log->free_queue); + DATA_S_List_init(&log->wr_queue); -static int8_t init_log_lists(Log *log) -{ - if (!log) return -1; - - DATA_S_List_init (&log->free_queue); - DATA_S_List_init (&log->wr_queue); - - for (uint16_t i = 0; i < LOG_MAX_BUFFER; i++) - { - if (LOG_Buffer_init(&log->buffer_pool[i]) == -1) return -1; - DATA_S_List_append(&the_log.free_queue, &log->buffer_pool[i].node); - } + for (uint16_t i = 0; i < LOG_MAX_BUFFER; i++) { + if (LOG_Buffer_init(&log->buffer_pool[i]) == -1) return -1; + DATA_S_List_append(&the_log.free_queue, &log->buffer_pool[i].node); + } - return 0; + return 0; } -int8_t LOG_prep() -{ - memset(&the_log, 0, sizeof(Log)); - the_log.buffer_pool = (LOG_Buffer*) malloc(LOG_MAX_BUFFER * sizeof(LOG_Buffer)); - the_log.pool_count = LOG_MAX_BUFFER; - - if (-1 == pthread_mutex_init(&the_log.gen_lock, NULL)) return -1; - if (-1 == pthread_mutex_init(&the_log.wr_lock, NULL)) return -1; - if (-1 == pthread_mutex_init(&the_log.free_lock, NULL)) return -1; - if (-1 == init_log_lists(&the_log)) return -1; - the_log.config.print_loc = LOG_USE_LOCATION; - the_log.fd = -1; - return 0; +int8_t LOG_prep() { + memset(&the_log, 0, sizeof(Log)); + the_log.buffer_pool = + (LOG_Buffer *)malloc(LOG_MAX_BUFFER * sizeof(LOG_Buffer)); + the_log.pool_count = LOG_MAX_BUFFER; + + if (-1 == pthread_mutex_init(&the_log.gen_lock, NULL)) return -1; + if (-1 == pthread_mutex_init(&the_log.wr_lock, NULL)) return -1; + if (-1 == pthread_mutex_init(&the_log.free_lock, NULL)) return -1; + if (-1 == init_log_lists(&the_log)) return -1; + the_log.config.print_loc = LOG_USE_LOCATION; + the_log.fd = -1; + return 0; } -int8_t LOG_init(const char* log_loc) -{ - if (!log_loc) STD_FAIL; - the_log.config.path = log_loc; - the_log.fd = open(the_log.config.path, LOG_FILE_FLAG, LOG_FILE_PERM); - if (-1 == the_log.fd) LOG_WARN("Invalid log file path: (%d) %s", errno, strerror(errno)); - LOG_INFO("Log Module Initialized."); - return 0; +int8_t LOG_init(const char *log_loc) { + if (!log_loc) STD_FAIL; + the_log.config.path = log_loc; + the_log.fd = open(the_log.config.path, LOG_FILE_FLAG, LOG_FILE_PERM); + if (-1 == the_log.fd) + LOG_WARN("Invalid log file path: (%d) %s", errno, strerror(errno)); + LOG_INFO("Log Module Initialized."); + return 0; } -int8_t LOG_start() -{ - pthread_create(&the_log.ptid, NULL, LOG_run, NULL); - the_log.config.en = true; - LOG_INFO("Log Module Running..."); - return 0; +int8_t LOG_start() { + pthread_create(&the_log.ptid, NULL, LOG_run, NULL); + the_log.config.en = true; + LOG_INFO("Log Module Running..."); + return 0; } -int8_t LOG_stop() -{ - the_log.config.en = false; // Prevent new log statements - pthread_join(the_log.ptid, NULL); - return 0; +int8_t LOG_stop() { + the_log.config.en = false; // Prevent new log statements + pthread_join(the_log.ptid, NULL); + return 0; } -int8_t LOG_destory() -{ - if(-1 != the_log.fd) close(the_log.fd); - pthread_mutex_destroy(&the_log.gen_lock); - DATA_S_List_deinit(&the_log.free_queue); - the_log.pool_count = 0; - if(the_log.buffer_pool) - { - free(the_log.buffer_pool); - the_log.buffer_pool = NULL; - } - return -1; +int8_t LOG_destory() { + if (-1 != the_log.fd) close(the_log.fd); + pthread_mutex_destroy(&the_log.gen_lock); + DATA_S_List_deinit(&the_log.free_queue); + the_log.pool_count = 0; + if (the_log.buffer_pool) { + free(the_log.buffer_pool); + the_log.buffer_pool = NULL; + } + return -1; } \ No newline at end of file diff --git a/src/common/log/log.h b/src/common/log/log.h index 67f83d4..b9130f3 100644 --- a/src/common/log/log.h +++ b/src/common/log/log.h @@ -1,15 +1,16 @@ /** * Logging Module * Creates realtime logs to help the debugging process - * + * * Features: * - Console and File logging * - Prioritization levels - * - Adjustable priority thresholds for console and file log outputs on a file-by-file basis + * - Adjustable priority thresholds for console and file log outputs on a + * file-by-file basis * - ISO6801 Timestamps * - Optional color-coding * - Non-blocking (runs in separate thread) -*/ + */ #pragma once @@ -17,8 +18,8 @@ #include // #include -#include "log/log_ansi_color.h" #include "data/s_list.h" +#include "log/log_ansi_color.h" #define LOG_USE_LOCATION false #define LOG_USE_COLOR true @@ -30,80 +31,79 @@ // Location info is considered part of the message body #define LOG_MAX_BUFFER 127 #define LOG_BUFFER_LEN 255 -#define LOG_HEADER_LEN 27 +#define LOG_HEADER_LEN 27 #define LOG_MESSAGE_LEN (LOG_BUFFER_LEN - LOG_HEADER_LEN) -#define LOG_POLL_PERIOD_US (25*1000) +#define LOG_POLL_PERIOD_US (25 * 1000) // Preprocessor abuse -#define LOG_LEVEL_ENTRIES \ - LOG_LEVEL_ENTRY(FATAL), \ - LOG_LEVEL_ENTRY(ERROR), \ - LOG_LEVEL_ENTRY(WARN), \ - LOG_LEVEL_ENTRY(INFO), \ - LOG_LEVEL_ENTRY(VERBOSE) // Always last - -#define LOG_LEVEL_ENTRY(entry) LOG_ ## entry -typedef enum _log_level -{ - LOG_LEVEL_ENTRIES -} LOG_level; +#define LOG_LEVEL_ENTRIES \ + LOG_LEVEL_ENTRY(FATAL), LOG_LEVEL_ENTRY(ERROR), LOG_LEVEL_ENTRY(WARN), \ + LOG_LEVEL_ENTRY(INFO), LOG_LEVEL_ENTRY(VERBOSE) // Always last +#define LOG_LEVEL_ENTRY(entry) LOG_##entry +typedef enum _log_level { LOG_LEVEL_ENTRIES } LOG_level; -extern const char* const _LOG_level_color[]; -extern const char* const log_level_names[]; +extern const char *const _LOG_level_color[]; +extern const char *const log_level_names[]; // Threshold shortcuts -#define LOG_THRESHOLD_DEFAULT (LOG_INFO) -#define LOG_THRESHOLD_MAX (LOG_VERBOSE + 9) -#define LOG_THRESHOLD_QUIET (LOG_ERROR) -#define LOG_THRESHOLD_SILENT (LOG_FATAL - 1) +#define LOG_THRESHOLD_DEFAULT (LOG_INFO) +#define LOG_THRESHOLD_MAX (LOG_VERBOSE + 9) +#define LOG_THRESHOLD_QUIET (LOG_ERROR) +#define LOG_THRESHOLD_SILENT (LOG_FATAL - 1) // Log shortcuts -#define LOG_FATAL(fmt, ...) LOG_write((uint8_t)LOG_FATAL, fmt, ##__VA_ARGS__) -#define LOG_ERROR(fmt, ...) LOG_write((uint8_t)LOG_ERROR, fmt, ##__VA_ARGS__) -#define LOG_IEC() LOG_ERROR("Internal error: %s:%d", __FILE__, __LINE__); -#define LOG_WARN(fmt, ...) LOG_write((uint8_t)LOG_WARN, fmt, ##__VA_ARGS__) -#define LOG_INFO(fmt, ...) LOG_write((uint8_t)LOG_INFO, fmt, ##__VA_ARGS__) -#define LOG_VERBOSE(v_level, fmt, ...) LOG_write((uint8_t)LOG_VERBOSE + v_level, fmt, ##__VA_ARGS__) -#define LOG_write(level, fmt, ...) LOG_print(__FILE__, __LINE__, LOG_CONSOLE_THRESHOLD_THIS, LOG_FILE_THRESHOLD_THIS, level, fmt, ##__VA_ARGS__) +#define LOG_FATAL(fmt, ...) LOG_write((uint8_t)LOG_FATAL, fmt, ##__VA_ARGS__) +#define LOG_ERROR(fmt, ...) LOG_write((uint8_t)LOG_ERROR, fmt, ##__VA_ARGS__) +#define LOG_IEC() LOG_ERROR("Internal error: %s:%d", __FILE__, __LINE__); +#define LOG_WARN(fmt, ...) LOG_write((uint8_t)LOG_WARN, fmt, ##__VA_ARGS__) +#define LOG_INFO(fmt, ...) LOG_write((uint8_t)LOG_INFO, fmt, ##__VA_ARGS__) +#define LOG_VERBOSE(v_level, fmt, ...) \ + LOG_write((uint8_t)LOG_VERBOSE + v_level, fmt, ##__VA_ARGS__) +#define LOG_write(level, fmt, ...) \ + LOG_print(__FILE__, __LINE__, LOG_CONSOLE_THRESHOLD_THIS, \ + LOG_FILE_THRESHOLD_THIS, level, fmt, ##__VA_ARGS__) /** * @brief Creates an asynchronous print request * @return 0 on success, -1 on failure -*/ -int8_t LOG_print(const char* file, uint16_t line, int8_t console_threshold, int8_t file_threshold, int8_t level, const char* fmt, ...); + */ +int8_t LOG_print(const char *file, uint16_t line, int8_t console_threshold, + int8_t file_threshold, int8_t level, const char *fmt, ...); /** - * @brief Prepares the logs functions; Should be one of the very first lines in an application - * @details Prepares the log resources, so logs can be written whether the Log module has been initialized/started, or not + * @brief Prepares the logs functions; Should be one of the very first lines in + * an application + * @details Prepares the log resources, so logs can be written whether the Log + * module has been initialized/started, or not * @returns 0 on success, -1 on failure -*/ + */ int8_t LOG_prep(); /** * @brief Initializes the Log thread for running * @param log_loc Location of the log file * @return 0 on success, -1 on failure -*/ -int8_t LOG_init(const char* log_loc); + */ +int8_t LOG_init(const char *log_loc); /** * @brief Starts the log thread * @return 0 on success, -1 on failure -*/ + */ int8_t LOG_start(); /** * @brief Stops the log thread. Blocks until all requests are handled * @return 0 on success, -1 on failure -*/ + */ int8_t LOG_stop(); /** * @brief Releases initialized resources from module * @return 0 on success, -1 on failure -*/ + */ int8_t LOG_destory(); \ No newline at end of file diff --git a/src/common/log/log_ansi_color.h b/src/common/log/log_ansi_color.h index ed7e29b..026dcbc 100644 --- a/src/common/log/log_ansi_color.h +++ b/src/common/log/log_ansi_color.h @@ -4,7 +4,7 @@ * For more information, please refer to */ -//Regular text +// Regular text #define BLK "\e[0;30m" #define RED "\e[0;31m" #define GRN "\e[0;32m" @@ -14,7 +14,7 @@ #define CYN "\e[0;36m" #define WHT "\e[0;37m" -//Regular bold text +// Regular bold text #define BBLK "\e[1;30m" #define BRED "\e[1;31m" #define BGRN "\e[1;32m" @@ -24,7 +24,7 @@ #define BCYN "\e[1;36m" #define BWHT "\e[1;37m" -//Regular underline text +// Regular underline text #define UBLK "\e[4;30m" #define URED "\e[4;31m" #define UGRN "\e[4;32m" @@ -34,7 +34,7 @@ #define UCYN "\e[4;36m" #define UWHT "\e[4;37m" -//Regular background +// Regular background #define BLKB "\e[40m" #define REDB "\e[41m" #define GRNB "\e[42m" @@ -44,7 +44,7 @@ #define CYNB "\e[46m" #define WHTB "\e[47m" -//High intensty background +// High intensty background #define BLKHB "\e[0;100m" #define REDHB "\e[0;101m" #define GRNHB "\e[0;102m" @@ -54,7 +54,7 @@ #define CYNHB "\e[0;106m" #define WHTHB "\e[0;107m" -//High intensty text +// High intensty text #define HBLK "\e[0;90m" #define HRED "\e[0;91m" #define HGRN "\e[0;92m" @@ -64,7 +64,7 @@ #define HCYN "\e[0;96m" #define HWHT "\e[0;97m" -//Bold high intensity text +// Bold high intensity text #define BHBLK "\e[1;90m" #define BHRED "\e[1;91m" #define BHGRN "\e[1;92m" @@ -74,7 +74,7 @@ #define BHCYN "\e[1;96m" #define BHWHT "\e[1;97m" -//Reset -// #define reset "\e[0m" +// Reset +// #define reset "\e[0m" #define CRESET "\e[0m" #define COLOR_RESET "\e[0m" diff --git a/src/common/log/log_config.cpp b/src/common/log/log_config.cpp index 34b7145..aac79d5 100644 --- a/src/common/log/log_config.cpp +++ b/src/common/log/log_config.cpp @@ -1,30 +1,23 @@ +#include "log/log_config.h" + #include #include -#include "log/log_config.h" #include "conf/config.h" #include "util/comm.h" -#define LOG_CONSOLE_THRESHOLD_THIS LOG_THRESHOLD_MAX -#define LOG_FILE_THRESHOLD_THIS LOG_THRESHOLD_MAX +#define LOG_CONSOLE_THRESHOLD_THIS LOG_THRESHOLD_MAX +#define LOG_FILE_THRESHOLD_THIS LOG_THRESHOLD_MAX -LogConfig::LogConfig() -{ - log_loc_idx = AddKey(LOG_CONF_LOC_KEY, LOG_CONF_LOC_DEFAULT); +LogConfig::LogConfig() { + log_loc_idx = AddKey(LOG_CONF_LOC_KEY, LOG_CONF_LOC_DEFAULT); } -LogConfig::~LogConfig() -{ - -} +LogConfig::~LogConfig() {} -int LogConfig::SetLogLocation(const char* log_location) -{ - if(!log_location) STD_FAIL; - return OverrideValue(log_loc_idx, log_location); +int LogConfig::SetLogLocation(const char *log_location) { + if (!log_location) STD_FAIL; + return OverrideValue(log_loc_idx, log_location); } -const char* LogConfig::GetLogLocation() -{ - return GetVal(log_loc_idx); -} \ No newline at end of file +const char *LogConfig::GetLogLocation() { return GetVal(log_loc_idx); } \ No newline at end of file diff --git a/src/common/log/log_config.h b/src/common/log/log_config.h index 206f9d7..5f73dcc 100644 --- a/src/common/log/log_config.h +++ b/src/common/log/log_config.h @@ -2,18 +2,18 @@ #include "conf/config.h" -#define LOG_CONF_LOC_KEY "log_loc" -#define LOG_CONF_LOC_DEFAULT "/etc/talos/logs/operator.log" +#define LOG_CONF_LOC_KEY "log_loc" +#define LOG_CONF_LOC_DEFAULT "/etc/talos/logs/operator.log" -class LogConfig: virtual public Config -{ - private: - int log_loc_idx; /** Where to put the log file generated by the logging module */ +class LogConfig : virtual public Config { + private: + int log_loc_idx; /** Where to put the log file generated by the logging module + */ - public: - LogConfig(); - ~LogConfig(); + public: + LogConfig(); + ~LogConfig(); - const char* GetLogLocation(); - int SetLogLocation(const char* log_location); + const char *GetLogLocation(); + int SetLogLocation(const char *log_location); }; \ No newline at end of file diff --git a/src/common/log/log_private.h b/src/common/log/log_private.h index 54bb584..45fcb42 100644 --- a/src/common/log/log_private.h +++ b/src/common/log/log_private.h @@ -3,68 +3,67 @@ #pragma once #include +#include #include #include -#include #include "data/s_list.h" #include "log/log.h" -const char* const _LOG_level_color[] = -{ - BRED, // Fatal - RED, // Error - YEL, // Warn - BLU, // Info - WHT, // Verbose +const char *const _LOG_level_color[] = { + BRED, // Fatal + RED, // Error + YEL, // Warn + BLU, // Info + WHT, // Verbose }; #ifdef LOG_LEVEL_ENTRY #undef LOG_LEVEL_ENTRY #endif #define LOG_LEVEL_ENTRY(entry) #entry - const char* const log_level_names[] = {LOG_LEVEL_ENTRIES}; +const char *const log_level_names[] = {LOG_LEVEL_ENTRIES}; #undef LOG_LEVEL_ENTRY /** Buffer for Log Entry */ -typedef struct _log_buffer -{ - uint8_t flags; - #define LOG_BUFFER_FLAG_OUT_CONSOLE 0 /** Flag for writing to console */ - #define LOG_BUFFER_FLAG_OUT_FILE 1 /** Flag for writing to file */ +typedef struct _log_buffer { + uint8_t flags; +#define LOG_BUFFER_FLAG_OUT_CONSOLE 0 /** Flag for writing to console */ +#define LOG_BUFFER_FLAG_OUT_FILE 1 /** Flag for writing to file */ - struct timespec timestamp; /** Timestamp of when the log message was submitted to the wr_queue */ - int8_t level; /** Priority level of message */ - char msg[LOG_MESSAGE_LEN]; /** Message content */ - uint8_t len; /** Length of message in bytes */ - S_List_Node node; /** Node for tracking buffer through queues */ + struct timespec timestamp; /** Timestamp of when the log message was submitted + to the wr_queue */ + int8_t level; /** Priority level of message */ + char msg[LOG_MESSAGE_LEN]; /** Message content */ + uint8_t len; /** Length of message in bytes */ + S_List_Node node; /** Node for tracking buffer through queues */ } LOG_Buffer; /** Log Module Configuration */ -typedef struct _log_config -{ - bool en; /** Indicates log enabled vs disabled */ - bool print_loc; /** Indicates whether or not to print source file locations */ - const char *path; /** Path of log file */ +typedef struct _log_config { + bool en; /** Indicates log enabled vs disabled */ + bool print_loc; /** Indicates whether or not to print source file locations */ + const char *path; /** Path of log file */ } LOG_Config; /** Log Module Resources */ -typedef struct _log -{ - pthread_t ptid; /** Pthread ID of Log Module thread */ - pthread_mutex_t gen_lock; /** Generic Lock */ - pthread_mutex_t wr_lock; /** Lock protecting the wr_queue */ - pthread_mutex_t free_lock; /** Lock protecting the free_queue */ - LOG_Config config; /** Configuration */ - // LOG_Buffer buffer_pool[LOG_MAX_BUFFER]; /** Statically allocated pool of Log buffers to rotate through */ - uint32_t pool_count; /** Number of LOG_Buffers in buffer_pool */ - LOG_Buffer *buffer_pool; /** Dynamically allocated pool of Log buffers to rotate through */ - S_List wr_queue; /** Queue of Log Buffers waiting to write to console/file */ - S_List free_queue; /** Queue of available Log Buffers */ - int fd; /** Log file descriptor */ +typedef struct _log { + pthread_t ptid; /** Pthread ID of Log Module thread */ + pthread_mutex_t gen_lock; /** Generic Lock */ + pthread_mutex_t wr_lock; /** Lock protecting the wr_queue */ + pthread_mutex_t free_lock; /** Lock protecting the free_queue */ + LOG_Config config; /** Configuration */ + // LOG_Buffer buffer_pool[LOG_MAX_BUFFER]; /** Statically allocated pool + // of Log buffers to rotate through */ + uint32_t pool_count; /** Number of LOG_Buffers in buffer_pool */ + LOG_Buffer *buffer_pool; /** Dynamically allocated pool of Log buffers to + rotate through */ + S_List wr_queue; /** Queue of Log Buffers waiting to write to console/file */ + S_List free_queue; /** Queue of available Log Buffers */ + int fd; /** Log file descriptor */ } Log; // Private functions -void LOG_thread_poll (); +void LOG_thread_poll(); void LOG_thread_print(); \ No newline at end of file diff --git a/src/common/socket/socket.cpp b/src/common/socket/socket.cpp index f5a2b3a..78a73c8 100644 --- a/src/common/socket/socket.cpp +++ b/src/common/socket/socket.cpp @@ -1,230 +1,210 @@ -#include +#include "socket/socket.h" + #include #include -#include #include +#include +#include -#include "socket/socket.h" -#include "util/comm.h" -#include "util/array.h" -#include "log/log.h" #include "api/api.h" +#include "log/log.h" +#include "util/array.h" +#include "util/comm.h" -#define LOG_CONSOLE_THRESHOLD_THIS LOG_THRESHOLD_DEFAULT -#define LOG_FILE_THRESHOLD_THIS LOG_THRESHOLD_MAX - -static int init_socket(Socket_Props* props) -{ - // Set up socket - props->sockfd = socket(AF_INET, SOCK_STREAM | SOCK_NONBLOCK, 0); - if (props->sockfd < 0) - { - LOG_ERROR("Could not open socket: (%d) %s", errno, strerror(errno)); - STD_FAIL; - } - - int optval = 1; - setsockopt(props->sockfd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)); - - // Set up server address configuration - memset(&props->server, 0, sizeof(props->server)); - props->port = 61616; - props->server.sin_family = AF_INET; - props->server.sin_addr.s_addr = INADDR_ANY; - props->server.sin_port = htons(props->port); - - // Bind socket with server address configuration - if (bind(props->sockfd, (struct sockaddr *) &props->server, sizeof(props->server)) < 0) - { - LOG_ERROR("Could not bind socket: (%d) %s", errno, strerror(errno)); - STD_FAIL; - } - - return 0; +#define LOG_CONSOLE_THRESHOLD_THIS LOG_THRESHOLD_DEFAULT +#define LOG_FILE_THRESHOLD_THIS LOG_THRESHOLD_MAX + +static int init_socket(Socket_Props *props) { + // Set up socket + props->sockfd = socket(AF_INET, SOCK_STREAM | SOCK_NONBLOCK, 0); + if (props->sockfd < 0) { + LOG_ERROR("Could not open socket: (%d) %s", errno, strerror(errno)); + STD_FAIL; + } + + int optval = 1; + setsockopt(props->sockfd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)); + + // Set up server address configuration + memset(&props->server, 0, sizeof(props->server)); + props->port = 61616; + props->server.sin_family = AF_INET; + props->server.sin_addr.s_addr = INADDR_ANY; + props->server.sin_port = htons(props->port); + + // Bind socket with server address configuration + if (bind(props->sockfd, (struct sockaddr *)&props->server, + sizeof(props->server)) < 0) { + LOG_ERROR("Could not bind socket: (%d) %s", errno, strerror(errno)); + STD_FAIL; + } + + return 0; } -Socket::Socket() -{ - // Create socket - init_socket(&props); - props.connfd = -1; +Socket::Socket() { + // Create socket + init_socket(&props); + props.connfd = -1; } -Socket::~Socket() -{ - if (-1 != props.connfd) close(props.connfd); - if (-1 != props.sockfd) close(props.sockfd); +Socket::~Socket() { + if (-1 != props.connfd) close(props.connfd); + if (-1 != props.sockfd) close(props.sockfd); } -static int wait_for_connection(Socket_Props* props) -{ - // Accept connection - socklen_t len = sizeof(props->client); - LOG_INFO("Waiting for client..."); - - while(props->thread_en && props->connfd < 0) - { - props->connfd = accept(props->sockfd, (struct sockaddr *) &props->client, &len); - usleep(SOCKET_POLL_PERIOD_MS * 1000); - if (-1 == props->connfd && errno != EAGAIN) - { - LOG_ERROR("Socket accept failed: (%d) %s", errno, strerror(errno)); - STD_FAIL; - } +static int wait_for_connection(Socket_Props *props) { + // Accept connection + socklen_t len = sizeof(props->client); + LOG_INFO("Waiting for client..."); + + while (props->thread_en && props->connfd < 0) { + props->connfd = + accept(props->sockfd, (struct sockaddr *)&props->client, &len); + usleep(SOCKET_POLL_PERIOD_MS * 1000); + if (-1 == props->connfd && errno != EAGAIN) { + LOG_ERROR("Socket accept failed: (%d) %s", errno, strerror(errno)); + STD_FAIL; } + } - if (props->connfd < 0) - { - LOG_INFO("Connection Failed."); - STD_FAIL; - } + if (props->connfd < 0) { + LOG_INFO("Connection Failed."); + STD_FAIL; + } - LOG_INFO ("Connection Established."); - return 0; + LOG_INFO("Connection Established."); + return 0; } -int send_response(Socket_Props* props) -{ - const char* response = "Message Received."; // placeholder response - int send_ret = send(props->connfd, response, strlen(response), 0); +int send_response(Socket_Props *props) { + const char *response = "Message Received."; // placeholder response + int send_ret = send(props->connfd, response, strlen(response), 0); - if (send_ret < 0) - { - LOG_ERROR("Response failed to send."); - STD_FAIL; - } - else - { - LOG_INFO("Response successfully sent"); - return 0; - } + if (send_ret < 0) { + LOG_ERROR("Response failed to send."); + STD_FAIL; + } else { + LOG_INFO("Response successfully sent"); + return 0; + } } -static void* socket_poll (void* arg) -{ - Socket_Props* props = (Socket_Props*) arg; - Subscriber* sub = props->sub; +static void *socket_poll(void *arg) { + Socket_Props *props = (Socket_Props *)arg; + Subscriber *sub = props->sub; - struct timeval last_ping; - bool idle = true; - int ret = 0; - uint16_t buf_iter = 0; - char buffer[SOCKET_BUF_LEN]; + struct timeval last_ping; + bool idle = true; + int ret = 0; + uint16_t buf_iter = 0; + char buffer[SOCKET_BUF_LEN]; - memset(&buffer[0], 0, SOCKET_BUF_LEN); + memset(&buffer[0], 0, SOCKET_BUF_LEN); - // Creates initial connection - if (wait_for_connection(props) != 0) - { - LOG_ERROR("Connection initialization failed."); - return NULL; + // Creates initial connection + if (wait_for_connection(props) != 0) { + LOG_ERROR("Connection initialization failed."); + return NULL; + } + + gettimeofday(&last_ping, NULL); + while (props->thread_en) { + if (idle) usleep(SOCKET_POLL_PERIOD_MS * 1000); + idle = true; + + // Handle rx + ret = recv(props->connfd, &buffer[buf_iter], sizeof(buffer) - buf_iter, + MSG_DONTWAIT); + if (-1 == ret) { + // errno will be set to EAGAIN if no message was received + if (EAGAIN == errno) continue; + + // Some other error; Exit execution + LOG_FATAL("Socket read error: (%d) %s", errno, strerror(errno)); + LOG_IEC(); + break; } - gettimeofday(&last_ping, NULL); - while(props->thread_en) - { - if (idle) usleep (SOCKET_POLL_PERIOD_MS * 1000); - idle = true; - - // Handle rx - ret = recv(props->connfd, &buffer[buf_iter], sizeof(buffer) - buf_iter, MSG_DONTWAIT); - if (-1 == ret) - { - // errno will be set to EAGAIN if no message was received - if (EAGAIN == errno) continue; - - // Some other error; Exit execution - LOG_FATAL("Socket read error: (%d) %s", errno, strerror(errno)); - LOG_IEC(); - break; - } - - if (0 == ret) - { - // Getting to this point should mean that the connection closed - // (otherwise recv would return -1 for a lack of a message) - - LOG_INFO("Connection closed by client."); - - close(props->connfd); - props->connfd = -1; - - if(wait_for_connection(props) != 0) - { - LOG_ERROR("Reconnection failed."); - break; - } - - continue; // continue receiving after reconnection - } - - // gettimeofday(&last_ping, NULL); - idle = false; - buf_iter += ret; - - while (buf_iter >= sizeof(API_Data_Header) + 2) - { - API_Data_Wrapper* msg = (API_Data_Wrapper*) &buffer[0]; - - // Check length - uint16_t len = sizeof(API_Data_Header) + be16toh(msg->header.len) + 2; - if (buf_iter < len) break; - - // Enqueue copied message to command buffer - SUB_Buffer* buf = sub->DequeueBuffer(SUB_QUEUE_FREE); - if (!buf) - { - LOG_WARN ("No free network buffers"); // You DDOS'd yourself. - break; - } - - buf->len = len; - memcpy(&buf->body[0], msg, buf->len); - sub->EnqueueBuffer(SUB_QUEUE_COMMAND, buf); - LOG_VERBOSE(2, "Received ICD command"); - - // Re-align buffer - buf_iter -= len; - memcpy(&buffer[0], &buffer[len], buf_iter); - - send_response(props); - } - } + if (0 == ret) { + // Getting to this point should mean that the connection closed + // (otherwise recv would return -1 for a lack of a message) - // Empty receive buffer; avoid TIME_WAIT on socket - LOG_IEC(); - if(-1 == shutdown(props->connfd, SHUT_RDWR)) LOG_ERROR("Error shutting down socket: (%d) %s", errno, strerror(errno)); - while (recv(props->connfd, &buffer[0], sizeof(buffer), 0) > 0); - if (-1 != props->connfd) - { - close (props->connfd); - props->connfd = -1; + LOG_INFO("Connection closed by client."); + + close(props->connfd); + props->connfd = -1; + + if (wait_for_connection(props) != 0) { + LOG_ERROR("Reconnection failed."); + break; + } + + continue; // continue receiving after reconnection } - return NULL; + // gettimeofday(&last_ping, NULL); + idle = false; + buf_iter += ret; + + while (buf_iter >= sizeof(API_Data_Header) + 2) { + API_Data_Wrapper *msg = (API_Data_Wrapper *)&buffer[0]; + + // Check length + uint16_t len = sizeof(API_Data_Header) + be16toh(msg->header.len) + 2; + if (buf_iter < len) break; + + // Enqueue copied message to command buffer + SUB_Buffer *buf = sub->DequeueBuffer(SUB_QUEUE_FREE); + if (!buf) { + LOG_WARN("No free network buffers"); // You DDOS'd yourself. + break; + } + + buf->len = len; + memcpy(&buf->body[0], msg, buf->len); + sub->EnqueueBuffer(SUB_QUEUE_COMMAND, buf); + LOG_VERBOSE(2, "Received ICD command"); + + // Re-align buffer + buf_iter -= len; + memcpy(&buffer[0], &buffer[len], buf_iter); + + send_response(props); + } + } + + // Empty receive buffer; avoid TIME_WAIT on socket + LOG_IEC(); + if (-1 == shutdown(props->connfd, SHUT_RDWR)) + LOG_ERROR("Error shutting down socket: (%d) %s", errno, strerror(errno)); + while (recv(props->connfd, &buffer[0], sizeof(buffer), 0) > 0); + if (-1 != props->connfd) { + close(props->connfd); + props->connfd = -1; + } + + return NULL; } -int Socket::Start() -{ - // Listen for connections - listen(props.sockfd, 5); +int Socket::Start() { + // Listen for connections + listen(props.sockfd, 5); - props.thread_en = true; - pthread_create(&pid, NULL, socket_poll, &props); - return 0; + props.thread_en = true; + pthread_create(&pid, NULL, socket_poll, &props); + return 0; } -int Socket::Stop() -{ - props.thread_en = false; - pthread_join(pid, NULL); // Wait for thread to exit - return 0; +int Socket::Stop() { + props.thread_en = false; + pthread_join(pid, NULL); // Wait for thread to exit + return 0; } -int Socket::RegisterSubscriber(Subscriber* sub) -{ - if (!sub) STD_FAIL; - this->sub = sub; - props.sub = sub; - return 0; +int Socket::RegisterSubscriber(Subscriber *sub) { + if (!sub) STD_FAIL; + this->sub = sub; + props.sub = sub; + return 0; } \ No newline at end of file diff --git a/src/common/socket/socket.h b/src/common/socket/socket.h index f017ac9..444c87d 100644 --- a/src/common/socket/socket.h +++ b/src/common/socket/socket.h @@ -1,13 +1,13 @@ #pragma once +#include +#include #include #include #include -#include -#include #include -#include -#include +#include +#include #include "sub/sub.h" @@ -16,43 +16,41 @@ #define SOCKET_PING_FREQ_MS 63 #define SOCKET_TIMEOUT_MS (4 * SOCKET_PING_FREQ_MS) -typedef struct _sock_props -{ - int sockfd = -1; - int connfd = -1; - int port; - struct sockaddr_in server; - struct sockaddr_in client; +typedef struct _sock_props { + int sockfd = -1; + int connfd = -1; + int port; + struct sockaddr_in server; + struct sockaddr_in client; - Subscriber *sub; - bool thread_en; + Subscriber *sub; + bool thread_en; } Socket_Props; -class Socket : public Inbox -{ - private: - int status = 0; - pthread_t pid = -1; +class Socket : public Inbox { + private: + int status = 0; + pthread_t pid = -1; - Socket_Props props; + Socket_Props props; - void* Poll(void* arg); + void *Poll(void *arg); - public: - Socket(); - ~Socket(); + public: + Socket(); + ~Socket(); - /** - * @brief Starts the Messenger service - * @return 0 on success, -1 on failure - */ - int Start(); + /** + * @brief Starts the Messenger service + * @return 0 on success, -1 on failure + */ + int Start(); - /** - * @brief Stops the Messenger service - * @return 0 on success, -1 on failure - */ - int Stop(); + /** + * @brief Stops the Messenger service + * @return 0 on success, -1 on failure + */ + int Stop(); - int RegisterSubscriber(Subscriber* sub); + int RegisterSubscriber(Subscriber *sub); }; \ No newline at end of file diff --git a/src/common/socket/socket_conf.cpp b/src/common/socket/socket_conf.cpp index c89c50a..a89a248 100644 --- a/src/common/socket/socket_conf.cpp +++ b/src/common/socket/socket_conf.cpp @@ -1,80 +1,66 @@ -#include -#include -#include +#include "socket/socket_conf.h" + #include #include - -#include "socket/socket_conf.h" +#include +#include +#include #include "conf/config.h" -#include "util/comm.h" #include "log/log.h" +#include "util/comm.h" -#define LOG_CONSOLE_THRESHOLD_THIS LOG_THRESHOLD_DEFAULT -#define LOG_FILE_THRESHOLD_THIS LOG_THRESHOLD_MAX +#define LOG_CONSOLE_THRESHOLD_THIS LOG_THRESHOLD_DEFAULT +#define LOG_FILE_THRESHOLD_THIS LOG_THRESHOLD_MAX -SocketConfig::SocketConfig() -{ - address_idx = AddKey(SOCKET_CONF_BINDING_ADDR_KEY, SOCKET_CONF_BINDING_ADDR_DEFAULT); - port_idx = AddKey(SOCKET_CONF_PORT_KEY, SOCKET_CONF_PORT_DEFAULT); +SocketConfig::SocketConfig() { + address_idx = + AddKey(SOCKET_CONF_BINDING_ADDR_KEY, SOCKET_CONF_BINDING_ADDR_DEFAULT); + port_idx = AddKey(SOCKET_CONF_PORT_KEY, SOCKET_CONF_PORT_DEFAULT); } -SocketConfig::~SocketConfig() -{ -} +SocketConfig::~SocketConfig() {} -uint32_t SocketConfig::GetBindingAddress() -{ - uint32_t val = 0; - int ret = inet_pton(AF_INET, GetVal(address_idx), &val); - if (1 == ret) return val; // Nominal return - - // Error handling - LOG_WARN("Failed to set user-defined binding address; using default"); - ret = inet_pton(AF_INET, SOCKET_CONF_BINDING_ADDR_DEFAULT, &val); - if (1 == ret) return val; // Default return - - // Default should always resolve; if you got here, you messed up. - LOG_FATAL("Binding address could not be set to default; ending program"); - raise(SIGABRT); - return 0; -} +uint32_t SocketConfig::GetBindingAddress() { + uint32_t val = 0; + int ret = inet_pton(AF_INET, GetVal(address_idx), &val); + if (1 == ret) return val; // Nominal return -int SocketConfig::SetBindingAddress(uint32_t addr) -{ - char tmp[32]; - if(NULL == inet_ntop (AF_INET, &addr, &tmp[0], 32)) - { - LOG_WARN("Failed to override binding address; bad address"); - STD_FAIL; - } + // Error handling + LOG_WARN("Failed to set user-defined binding address; using default"); + ret = inet_pton(AF_INET, SOCKET_CONF_BINDING_ADDR_DEFAULT, &val); + if (1 == ret) return val; // Default return - return SetBindingAddress((const char*) &tmp); + // Default should always resolve; if you got here, you messed up. + LOG_FATAL("Binding address could not be set to default; ending program"); + raise(SIGABRT); + return 0; } -int SocketConfig::SetBindingAddress(const char* addr) -{ - if(OverrideValue(address_idx, addr)) - { - LOG_WARN("Failed to override binding address; bad address"); - STD_FAIL; - } +int SocketConfig::SetBindingAddress(uint32_t addr) { + char tmp[32]; + if (NULL == inet_ntop(AF_INET, &addr, &tmp[0], 32)) { + LOG_WARN("Failed to override binding address; bad address"); + STD_FAIL; + } - return 0; + return SetBindingAddress((const char *)&tmp); } -uint16_t SocketConfig::GetPort() -{ - return GetInt(port_idx); +int SocketConfig::SetBindingAddress(const char *addr) { + if (OverrideValue(address_idx, addr)) { + LOG_WARN("Failed to override binding address; bad address"); + STD_FAIL; + } + + return 0; } -int SocketConfig::SetPort(uint16_t port) -{ - return OverrideValue(port_idx, port); +uint16_t SocketConfig::GetPort() { return GetInt(port_idx); } + +int SocketConfig::SetPort(uint16_t port) { + return OverrideValue(port_idx, port); } -int SocketConfig::LoadDefaults() -{ - return 0; -} \ No newline at end of file +int SocketConfig::LoadDefaults() { return 0; } \ No newline at end of file diff --git a/src/common/socket/socket_conf.h b/src/common/socket/socket_conf.h index 37250a4..7fe5f96 100644 --- a/src/common/socket/socket_conf.h +++ b/src/common/socket/socket_conf.h @@ -1,62 +1,61 @@ #pragma once #include + #include "conf/config.h" -#define SOCKET_CONF_BINDING_ADDR_KEY "socket_address" -#define SOCKET_CONF_BINDING_ADDR_DEFAULT "0.0.0.0" -#define SOCKET_CONF_PORT_KEY "socket_port" -#define SOCKET_CONF_PORT_DEFAULT 61616 - -class SocketConfig: virtual public Config -{ - private: - int address_idx; /** The server's binding IP address */ - int port_idx; /** The port the server will listen/bind on */ - - public: - SocketConfig(); - ~SocketConfig(); - - /** - * @brief Gets config for socket binding address - * @returns config string on success, NULL on failure - */ - uint32_t GetBindingAddress(); - - /** - * @brief Sets config for socket binding address - * @param addr binding address to set in config - * @returns 0 on success, -1 on failure - */ - int SetBindingAddress(uint32_t addr); - - - /** - * @brief Sets config for socket binding address - * @param addr binding address to set in config - * @returns 0 on success, -1 on failure - */ - int SetBindingAddress(const char* addr); - - /** - * @brief Gets config for socket port - * @param port port to set in config - * @returns 0 on success, -1 on failure - */ - uint16_t GetPort(); - - /** - * @brief Sets config for socket port - * @param port port to set in config - * @returns 0 on success, -1 on failure - */ - int SetPort(uint16_t port); - - /** - * @brief Loads the socket default configuration - * @details Clear Key-Val table before using LoadDefaults - * @returns 0 on success, -1 on failure - */ - int LoadDefaults(); +#define SOCKET_CONF_BINDING_ADDR_KEY "socket_address" +#define SOCKET_CONF_BINDING_ADDR_DEFAULT "0.0.0.0" +#define SOCKET_CONF_PORT_KEY "socket_port" +#define SOCKET_CONF_PORT_DEFAULT 61616 + +class SocketConfig : virtual public Config { + private: + int address_idx; /** The server's binding IP address */ + int port_idx; /** The port the server will listen/bind on */ + + public: + SocketConfig(); + ~SocketConfig(); + + /** + * @brief Gets config for socket binding address + * @returns config string on success, NULL on failure + */ + uint32_t GetBindingAddress(); + + /** + * @brief Sets config for socket binding address + * @param addr binding address to set in config + * @returns 0 on success, -1 on failure + */ + int SetBindingAddress(uint32_t addr); + + /** + * @brief Sets config for socket binding address + * @param addr binding address to set in config + * @returns 0 on success, -1 on failure + */ + int SetBindingAddress(const char *addr); + + /** + * @brief Gets config for socket port + * @param port port to set in config + * @returns 0 on success, -1 on failure + */ + uint16_t GetPort(); + + /** + * @brief Sets config for socket port + * @param port port to set in config + * @returns 0 on success, -1 on failure + */ + int SetPort(uint16_t port); + + /** + * @brief Loads the socket default configuration + * @details Clear Key-Val table before using LoadDefaults + * @returns 0 on success, -1 on failure + */ + int LoadDefaults(); }; \ No newline at end of file diff --git a/src/common/sub/inbox.h b/src/common/sub/inbox.h index d9df8a7..dd31fe0 100644 --- a/src/common/sub/inbox.h +++ b/src/common/sub/inbox.h @@ -6,36 +6,36 @@ class Subscriber; /** * @class Subscriber Messenger Interface - * @details Serves to separate the rest of the Talos Operator system from the messenger implementation (AMQ, HTTP, etc...) -*/ -class Inbox -{ -protected: - Subscriber* sub; - void OnMessage(); - -public: - /** - * @brief Constructor - */ - Inbox() {} - - /** - * @brief Destructor - */ - virtual ~Inbox() {} - - /** - * @brief Starts the Messenger service - * @return 0 on success, -1 on failure - */ - virtual int Start() = 0; - - /** - * @brief Stops the Messenger service - * @return 0 on success, -1 on failure - */ - virtual int Stop() = 0; - - virtual int RegisterSubscriber(Subscriber* sub) = 0; + * @details Serves to separate the rest of the Talos Operator system from the + * messenger implementation (AMQ, HTTP, etc...) + */ +class Inbox { + protected: + Subscriber *sub; + void OnMessage(); + + public: + /** + * @brief Constructor + */ + Inbox() {} + + /** + * @brief Destructor + */ + virtual ~Inbox() {} + + /** + * @brief Starts the Messenger service + * @return 0 on success, -1 on failure + */ + virtual int Start() = 0; + + /** + * @brief Stops the Messenger service + * @return 0 on success, -1 on failure + */ + virtual int Stop() = 0; + + virtual int RegisterSubscriber(Subscriber *sub) = 0; }; \ No newline at end of file diff --git a/src/common/sub/sub.cpp b/src/common/sub/sub.cpp index b191408..5dba2b5 100644 --- a/src/common/sub/sub.cpp +++ b/src/common/sub/sub.cpp @@ -1,172 +1,177 @@ -#include -#include +#include "sub/sub.h" + +#include #include #include +#include #include -#include -#include "sub/sub.h" -#include "sub/sub_private.h" -#include "util/comm.h" -#include "util/array.h" -#include "log/log.h" +#include "api/api.h" #include "data/list.h" #include "data/s_list.h" - -#include "api/api.h" +#include "log/log.h" +#include "sub/sub_private.h" +#include "util/array.h" +#include "util/comm.h" #define LOG_CONSOLE_THRESHOLD_THIS LOG_THRESHOLD_DEFAULT -#define LOG_FILE_THRESHOLD_THIS LOG_THRESHOLD_MAX +#define LOG_FILE_THRESHOLD_THIS LOG_THRESHOLD_MAX -#define SUB_ABORT {LOG_IEC(); Abort(); return -1;} +#define SUB_ABORT \ + { \ + LOG_IEC(); \ + Abort(); \ + return -1; \ + } /** * @brief Helper function to initialize Subscriber queues' locks and lists - * @param queue_idx SUB_Queue value corresponding to a specific queue's index in the array of queues + * @param queue_idx SUB_Queue value corresponding to a specific queue's index in + * the array of queues * @returns 0 on success, -1 on failure -*/ -static int init_queue(SUB_Instance& resources, SUB_Queue queue_idx) -{ - // If the message pool is NULL (unallocated), allocate a new pool. - // If the message pool is not NULL, assume it has been allocated already (length is compile time constant) - if (!resources.msg_pool) resources.msg_pool = (SUB_Buffer*) malloc(SUB_MSG_COUNT * sizeof(SUB_Buffer)); - - if (pthread_mutex_init(&resources.locks[(uint8_t) queue_idx], NULL)) STD_FAIL - if (DATA_S_List_init(&resources.queues[(uint8_t) queue_idx])) STD_FAIL - - return 0; + */ +static int init_queue(SUB_Instance &resources, SUB_Queue queue_idx) { + // If the message pool is NULL (unallocated), allocate a new pool. + // If the message pool is not NULL, assume it has been allocated already + // (length is compile time constant) + if (!resources.msg_pool) + resources.msg_pool = + (SUB_Buffer *)malloc(SUB_MSG_COUNT * sizeof(SUB_Buffer)); + + if (pthread_mutex_init(&resources.locks[(uint8_t)queue_idx], NULL)) STD_FAIL + if (DATA_S_List_init(&resources.queues[(uint8_t)queue_idx])) STD_FAIL + + return 0; } /** * @brief Helper function to deinitialize Subscriber queues' locks and lists - * @param queue_idx SUB_Queue value corresponding to a specific queue's index in the array of queues + * @param queue_idx SUB_Queue value corresponding to a specific queue's index in + * the array of queues * @returns 0 on success, -1 on failure -*/ -static int deinit_queue(SUB_Instance& resources, SUB_Queue queue_idx) -{ - pthread_mutex_t *mutex = &resources.locks[(uint8_t) queue_idx]; + */ +static int deinit_queue(SUB_Instance &resources, SUB_Queue queue_idx) { + pthread_mutex_t *mutex = &resources.locks[(uint8_t)queue_idx]; - // Block until mutex is available, then unlock to destroy - // Threads should be disabled by this point - pthread_mutex_lock(mutex); - pthread_mutex_unlock(mutex); + // Block until mutex is available, then unlock to destroy + // Threads should be disabled by this point + pthread_mutex_lock(mutex); + pthread_mutex_unlock(mutex); - if (pthread_mutex_destroy(&resources.locks[(uint8_t) queue_idx])) STD_FAIL - if (DATA_S_List_deinit(&resources.queues[(uint8_t) queue_idx])) STD_FAIL + if (pthread_mutex_destroy(&resources.locks[(uint8_t)queue_idx])) STD_FAIL + if (DATA_S_List_deinit(&resources.queues[(uint8_t)queue_idx])) STD_FAIL - return 0; + return 0; } -static int SUB_prep_subscriber(SUB_Instance& resources) -{ - memset(&resources, 0, sizeof(SUB_Instance)); +static int SUB_prep_subscriber(SUB_Instance &resources) { + memset(&resources, 0, sizeof(SUB_Instance)); - for (uint8_t iter = 0; iter < SUB_QUEUE_LEN; iter++) - init_queue(resources, (SUB_Queue) iter); + for (uint8_t iter = 0; iter < SUB_QUEUE_LEN; iter++) + init_queue(resources, (SUB_Queue)iter); - pthread_mutex_lock(&resources.locks[SUB_QUEUE_FREE]); - for (uint16_t iter = 0; iter < SUB_MSG_COUNT; iter++) - { - SUB_Buffer* buf = &resources.msg_pool[iter]; - SUB_init_buffer (buf); - DATA_S_List_append(&resources.queues[SUB_QUEUE_FREE], &buf->node); - } - pthread_mutex_unlock(&resources.locks[SUB_QUEUE_FREE]); + pthread_mutex_lock(&resources.locks[SUB_QUEUE_FREE]); + for (uint16_t iter = 0; iter < SUB_MSG_COUNT; iter++) { + SUB_Buffer *buf = &resources.msg_pool[iter]; + SUB_init_buffer(buf); + DATA_S_List_append(&resources.queues[SUB_QUEUE_FREE], &buf->node); + } + pthread_mutex_unlock(&resources.locks[SUB_QUEUE_FREE]); - return 0; + return 0; } -static int SUB_deinit_subscriber(SUB_Instance& resources) -{ - for (uint8_t iter = 0; iter < SUB_QUEUE_LEN; iter++) - if (deinit_queue(resources, (SUB_Queue) iter)) STD_FAIL; +static int SUB_deinit_subscriber(SUB_Instance &resources) { + for (uint8_t iter = 0; iter < SUB_QUEUE_LEN; iter++) + if (deinit_queue(resources, (SUB_Queue)iter)) STD_FAIL; - if (resources.msg_pool) - { - free(resources.msg_pool); - resources.msg_pool = NULL; - } + if (resources.msg_pool) { + free(resources.msg_pool); + resources.msg_pool = NULL; + } - return 0; + return 0; } -Subscriber::Subscriber() -{ - LOG_INFO("Subscriber Initializing..."); +Subscriber::Subscriber() { + LOG_INFO("Subscriber Initializing..."); - SUB_prep_subscriber(resources); - status = SUB_State::INIT; - LOG_INFO("Subscriber Initialized."); + SUB_prep_subscriber(resources); + status = SUB_State::INIT; + LOG_INFO("Subscriber Initialized."); } -void Subscriber::Abort() -{ +void Subscriber::Abort() {} +Subscriber::~Subscriber() { + if (SUB_State::INIT != status) LOG_IEC(); + status = SUB_State::DEAD; + SUB_deinit_subscriber(resources); } -Subscriber::~Subscriber() -{ - if (SUB_State::INIT != status) LOG_IEC(); - status = SUB_State::DEAD; - SUB_deinit_subscriber(resources); -} +int Subscriber::Start() { + if (SUB_State::INIT != status) STD_FAIL; -int Subscriber::Start() -{ - if (SUB_State::INIT != status) STD_FAIL; + /* + // TODO: Implement responder + if (!responder) SUB_ABORT; + if (responder->Start()) STD_FAIL; + */ - /* - // TODO: Implement responder - if (!responder) SUB_ABORT; - if (responder->Start()) STD_FAIL; - */ + status = SUB_State::RUN; + return 0; +} + +int Subscriber::RegisterResponder(Inbox *responder) { + if (!responder) STD_FAIL; + if (SUB_State::RUN == status) + LOG_WARN("Registering a responder on a running Subscriber."); - status = SUB_State::RUN; - return 0; + this->responder = responder; + return 0; } -int Subscriber::Stop() -{ - if (SUB_State::RUN != status) STD_FAIL; - status = SUB_State::INIT; - return 0; +int Subscriber::Stop() { + if (SUB_State::RUN != status) STD_FAIL; + status = SUB_State::INIT; + return 0; } -int SUB_init_buffer(SUB_Buffer *buf) -{ - if (!buf) STD_FAIL; +int SUB_init_buffer(SUB_Buffer *buf) { + if (!buf) STD_FAIL; - memset(buf, 0, sizeof(SUB_Buffer)); - DATA_S_List_Node_init (&buf->node); - return 0; + memset(buf, 0, sizeof(SUB_Buffer)); + DATA_S_List_Node_init(&buf->node); + return 0; } -SUB_Buffer* Subscriber::DequeueBuffer(SUB_Queue queue_idx) -{ - if ((uint8_t) queue_idx >= SUB_MSG_LEN) STD_FAIL_VOID_PTR; +SUB_Buffer *Subscriber::DequeueBuffer(SUB_Queue queue_idx) { + if ((uint8_t)queue_idx >= SUB_MSG_LEN) STD_FAIL_VOID_PTR; - S_List_Node* node = NULL; - pthread_mutex_lock (&resources.locks [(uint8_t) queue_idx]); - node = DATA_S_List_pop (&resources.queues[(uint8_t) queue_idx]); - pthread_mutex_unlock (&resources.locks [(uint8_t) queue_idx]); + S_List_Node *node = NULL; + pthread_mutex_lock(&resources.locks[(uint8_t)queue_idx]); + node = DATA_S_List_pop(&resources.queues[(uint8_t)queue_idx]); + pthread_mutex_unlock(&resources.locks[(uint8_t)queue_idx]); - if (!node) return NULL; - LOG_VERBOSE(2, "SUB_Buffer dequeued from queue index #%d", (uint8_t) queue_idx); - return DATA_LIST_GET_OBJ(node, SUB_Buffer, node); + if (!node) return NULL; + LOG_VERBOSE(2, "SUB_Buffer dequeued from queue index #%d", + (uint8_t)queue_idx); + return DATA_LIST_GET_OBJ(node, SUB_Buffer, node); } -int Subscriber::EnqueueBuffer(SUB_Queue queue_idx, SUB_Buffer* buf) -{ - if (SUB_State::RUN != status) LOG_WARN("Enqueueing a buffer onto a stopped Subscriber."); - if (!buf) STD_FAIL; - if ((uint8_t) queue_idx >= SUB_MSG_LEN) STD_FAIL; - - if (SUB_QUEUE_FREE == queue_idx) SUB_init_buffer (buf); - pthread_mutex_lock (&resources.locks [(uint8_t) queue_idx]); - int ret = DATA_S_List_append (&resources.queues[(uint8_t) queue_idx], &buf->node); - pthread_mutex_unlock (&resources.locks [(uint8_t) queue_idx]); - - if (ret) STD_FAIL; - LOG_VERBOSE(2, "SUB_Buffer enqueued in queue index #%d", (uint8_t) queue_idx); - return 0; -} \ No newline at end of file +int Subscriber::EnqueueBuffer(SUB_Queue queue_idx, SUB_Buffer *buf) { + if (SUB_State::RUN != status) + LOG_WARN("Enqueueing a buffer onto a stopped Subscriber."); + if (!buf) STD_FAIL; + if ((uint8_t)queue_idx >= SUB_MSG_LEN) STD_FAIL; + + if (SUB_QUEUE_FREE == queue_idx) SUB_init_buffer(buf); + pthread_mutex_lock(&resources.locks[(uint8_t)queue_idx]); + int ret = + DATA_S_List_append(&resources.queues[(uint8_t)queue_idx], &buf->node); + pthread_mutex_unlock(&resources.locks[(uint8_t)queue_idx]); + + if (ret) STD_FAIL; + LOG_VERBOSE(2, "SUB_Buffer enqueued in queue index #%d", (uint8_t)queue_idx); + return 0; +} diff --git a/src/common/sub/sub.h b/src/common/sub/sub.h index ee2032a..eddf53f 100644 --- a/src/common/sub/sub.h +++ b/src/common/sub/sub.h @@ -1,110 +1,108 @@ /** * Subscriber Module - * Acts as the interface for the rest of the Operator system to send and receive messages. - * This includes, logs, return messages, etc. + * Acts as the interface for the rest of the Operator system to send and receive + * messages. This includes, logs, return messages, etc. * - * This interface is intended to be an agnostic interface to whatever messaging implementation is used to communicate with the director. -*/ + * This interface is intended to be an agnostic interface to whatever messaging + * implementation is used to communicate with the director. + */ #pragma once -#include #include +#include #include "data/s_list.h" -#include "util/comm.h" -#include "sub/sub.h" #include "sub/inbox.h" +#include "sub/sub.h" +#include "util/comm.h" #define SUB_MSG_LEN 255 #define SUB_MSG_COUNT 64 #define SUB_ADDR_LEN 32 /** List of queues tracking Subscriber Buffers */ -typedef enum _sub_queue -{ - SUB_QUEUE_FREE, /** Index of Free Queue */ - SUB_QUEUE_COMMAND, /** Index of Command Queue */ - SUB_QUEUE_RETURN, /** Index of Return Queue */ - SUB_QUEUE_LOG, /** Index of Log Queue */ - SUB_QUEUE_LEN, /** Always last; Equal to length of enum */ +typedef enum _sub_queue { + SUB_QUEUE_FREE, /** Index of Free Queue */ + SUB_QUEUE_COMMAND, /** Index of Command Queue */ + SUB_QUEUE_RETURN, /** Index of Return Queue */ + SUB_QUEUE_LOG, /** Index of Log Queue */ + SUB_QUEUE_LEN, /** Always last; Equal to length of enum */ } SUB_Queue; /** List of implemented Inbox classes */ -typedef enum _sub_msg_implementaion -{ - SUB_MSG_AMQ, +typedef enum _sub_msg_implementaion { + SUB_MSG_AMQ, } SUB_Concrete; /** Subscriber Buffer */ -typedef struct _sub_buf -{ - uint8_t body[SUB_MSG_LEN]; /** Message contents */ - uint8_t len; /** Message length */ - S_List_Node node; /** Tracks buffer through Subscriber Queues */ +typedef struct _sub_buf { + uint8_t body[SUB_MSG_LEN]; /** Message contents */ + uint8_t len; /** Message length */ + S_List_Node node; /** Tracks buffer through Subscriber Queues */ } SUB_Buffer; /** Resources for Subscriber messages */ -typedef struct _sub_instance -{ - // Inbox* cmd; /** Pointer to Concrete Subscriber instance */ - // SUB_Status status; /** Current status of subscriber interface */ - // SUB_Concrete sub_type; /** Stores the type of messenger being used (e.g.: TAMQ vs HTTP) */ - // SUB_Buffer msg_pool[SUB_MSG_COUNT]; /** Statically allocated pool of Sub Messages */ - uint32_t pool_len; /** Number of SUB_Buffers in the message pool */ - SUB_Buffer* msg_pool; /** Dynamically allocated pool of Sub Messages */ - pthread_mutex_t locks[SUB_QUEUE_LEN]; /** Subscriber queue locks; Indeces correspond to the SUB_Queue enum */ - S_List queues[SUB_QUEUE_LEN]; /** Subscriber queues; Indeces correspond to the SUB_Queue enum */ +typedef struct _sub_instance { + // Inbox* cmd; /** Pointer to Concrete Subscriber + // instance */ SUB_Status status; /** Current status + // of subscriber interface */ SUB_Concrete sub_type; /** + // Stores the type of messenger being used (e.g.: TAMQ vs HTTP) */ SUB_Buffer + // msg_pool[SUB_MSG_COUNT]; /** Statically allocated pool of Sub Messages + // */ + uint32_t pool_len; /** Number of SUB_Buffers in the message pool */ + SUB_Buffer *msg_pool; /** Dynamically allocated pool of Sub Messages */ + pthread_mutex_t locks[SUB_QUEUE_LEN]; /** Subscriber queue locks; Indeces + correspond to the SUB_Queue enum */ + S_List queues[SUB_QUEUE_LEN]; /** Subscriber queues; Indeces correspond to the + SUB_Queue enum */ } SUB_Instance; - /** * @brief Initializes a Subscriber Buffer struct * @param buf Pointer to a SUB_Buffer pointer * @returns 0 on success, -1 on failure -*/ + */ int SUB_init_buffer(SUB_Buffer *buf); -class Subscriber -{ - private: - enum class SUB_State - { - DEAD, - INIT, - RUN, - }; - - SUB_State status; /** Current status of subscriber interface */ - SUB_Instance resources; /** Resources for managing buffers */ - - public: - Subscriber(); - ~Subscriber(); - - int Start(); - int Stop(); - void Abort(); - - int RegisterResponder(Inbox* responder); - - // TODO: implement the following: - // int RegisterResponder(Inbox* responder); - // int RegisterLogger(Inbox* logger); - - /** - * @brief Enqueues a SUB_Buffer struct from the head of the specified list - * @param queue Queue to enqueue onto - * @param buf Buffer to enqueue - * @returns 0 on success, -1 on failure - */ - int EnqueueBuffer(SUB_Queue queue_idx, SUB_Buffer* buf); - - /** - * @brief Dequeues a SUB_Buffer struct from the head of the specified list - * @param queue Queue to dequeue from - * @returns SUB_Buffer pointer on success, NULL on failure - */ - SUB_Buffer* DequeueBuffer(SUB_Queue queue_idx); - -}; \ No newline at end of file +class Subscriber { + private: + enum class SUB_State { + DEAD, + INIT, + RUN, + }; + + SUB_State status; /** Current status of subscriber interface */ + SUB_Instance resources; /** Resources for managing buffers */ + Inbox *responder; /** Pointer to the responder inbox */ + + public: + Subscriber(); + ~Subscriber(); + + int Start(); + int Stop(); + void Abort(); + + int RegisterResponder(Inbox *responder); + + // TODO: implement the following: + // int RegisterResponder(Inbox* responder); + // int RegisterLogger(Inbox* logger); + + /** + * @brief Enqueues a SUB_Buffer struct from the head of the specified list + * @param queue Queue to enqueue onto + * @param buf Buffer to enqueue + * @returns 0 on success, -1 on failure + */ + int EnqueueBuffer(SUB_Queue queue_idx, SUB_Buffer *buf); + + /** + * @brief Dequeues a SUB_Buffer struct from the head of the specified list + * @param queue Queue to dequeue from + * @returns SUB_Buffer pointer on success, NULL on failure + */ + SUB_Buffer *DequeueBuffer(SUB_Queue queue_idx); +}; diff --git a/src/common/sub/sub_private.h b/src/common/sub/sub_private.h index 5274621..c28787c 100644 --- a/src/common/sub/sub_private.h +++ b/src/common/sub/sub_private.h @@ -1,9 +1,8 @@ #pragma once #include -#include "sub/sub.h" #include "data/s_list.h" - +#include "sub/sub.h" /** List of states the Inbox can be in */ // typedef enum _sub_status diff --git a/src/common/tamq/tamq_conf.cpp b/src/common/tamq/tamq_conf.cpp index f9fac8c..4540d8a 100644 --- a/src/common/tamq/tamq_conf.cpp +++ b/src/common/tamq/tamq_conf.cpp @@ -1,68 +1,48 @@ +#include "tamq/tamq_conf.h" + #include #include -#include "tamq/tamq_conf.h" #include "util/comm.h" -#define LOG_CONSOLE_THRESHOLD_THIS LOG_THRESHOLD_DEFAULT -#define LOG_FILE_THRESHOLD_THIS LOG_THRESHOLD_DEFAULT +#define LOG_CONSOLE_THRESHOLD_THIS LOG_THRESHOLD_DEFAULT +#define LOG_FILE_THRESHOLD_THIS LOG_THRESHOLD_DEFAULT -TAMQ_Config::TAMQ_Config() -{ - address_idx = AddKey(TAMQ_CONF_ADDR_KEY, TAMQ_CONF_ADDR_DEFAULT); - cmd_uri_idx = AddKey(TAMQ_CONF_CMD_URI_KEY, TAMQ_CONF_CMD_URI_DEFAULT); - ret_uri_idx = AddKey(TAMQ_CONF_RET_URI_KEY, TAMQ_CONF_RET_URI_DEFAULT); - log_uri_idx = AddKey(TAMQ_CONF_LOG_URI_KEY, TAMQ_CONF_LOG_URI_DEFAULT); +TAMQ_Config::TAMQ_Config() { + address_idx = AddKey(TAMQ_CONF_ADDR_KEY, TAMQ_CONF_ADDR_DEFAULT); + cmd_uri_idx = AddKey(TAMQ_CONF_CMD_URI_KEY, TAMQ_CONF_CMD_URI_DEFAULT); + ret_uri_idx = AddKey(TAMQ_CONF_RET_URI_KEY, TAMQ_CONF_RET_URI_DEFAULT); + log_uri_idx = AddKey(TAMQ_CONF_LOG_URI_KEY, TAMQ_CONF_LOG_URI_DEFAULT); - use_topics_idx = AddKey(TAMQ_CONF_USE_TOPICS_KEY, TAMQ_CONF_USE_TOPICS_DEFAULT); - client_ack_idx = AddKey(TAMQ_CONF_CLIENT_ACK_KEY, TAMQ_CONF_CLIENT_ACK_DEFAULT); + use_topics_idx = + AddKey(TAMQ_CONF_USE_TOPICS_KEY, TAMQ_CONF_USE_TOPICS_DEFAULT); + client_ack_idx = + AddKey(TAMQ_CONF_CLIENT_ACK_KEY, TAMQ_CONF_CLIENT_ACK_DEFAULT); } -TAMQ_Config::~TAMQ_Config() -{ +TAMQ_Config::~TAMQ_Config() {} -} +const char *TAMQ_Config::GetBrokerAddress() { return GetVal(address_idx); } -const char* TAMQ_Config::GetBrokerAddress() -{ - return GetVal(address_idx); -} +const char *TAMQ_Config::GetCommandURI() { return GetVal(cmd_uri_idx); } -const char* TAMQ_Config::GetCommandURI() -{ - return GetVal(cmd_uri_idx); -} +const char *TAMQ_Config::GetReturnsURI() { return GetVal(ret_uri_idx); } -const char* TAMQ_Config::GetReturnsURI() -{ - return GetVal(ret_uri_idx); -} +const char *TAMQ_Config::GetLogURI() { return GetVal(log_uri_idx); } -const char* TAMQ_Config::GetLogURI() -{ - return GetVal(log_uri_idx); -} +bool TAMQ_Config::GetUseTopics() { return GetBool(use_topics_idx); } -bool TAMQ_Config::GetUseTopics() -{ - return GetBool(use_topics_idx); -} - -bool TAMQ_Config::GetClientAck() -{ - return GetBool(client_ack_idx); -} +bool TAMQ_Config::GetClientAck() { return GetBool(client_ack_idx); } -int TAMQ_Config::LoadDefaults() -{ - int8_t counter = 0; - counter -= OverrideValue(address_idx, TAMQ_CONF_ADDR_DEFAULT); - counter -= OverrideValue(cmd_uri_idx, TAMQ_CONF_CMD_URI_DEFAULT); - counter -= OverrideValue(ret_uri_idx, TAMQ_CONF_RET_URI_DEFAULT); - counter -= OverrideValue(log_uri_idx, TAMQ_CONF_LOG_URI_DEFAULT); +int TAMQ_Config::LoadDefaults() { + int8_t counter = 0; + counter -= OverrideValue(address_idx, TAMQ_CONF_ADDR_DEFAULT); + counter -= OverrideValue(cmd_uri_idx, TAMQ_CONF_CMD_URI_DEFAULT); + counter -= OverrideValue(ret_uri_idx, TAMQ_CONF_RET_URI_DEFAULT); + counter -= OverrideValue(log_uri_idx, TAMQ_CONF_LOG_URI_DEFAULT); - counter -= OverrideValue(use_topics_idx, TAMQ_CONF_USE_TOPICS_DEFAULT); - counter -= OverrideValue(client_ack_idx, TAMQ_CONF_CLIENT_ACK_DEFAULT); + counter -= OverrideValue(use_topics_idx, TAMQ_CONF_USE_TOPICS_DEFAULT); + counter -= OverrideValue(client_ack_idx, TAMQ_CONF_CLIENT_ACK_DEFAULT); - return counter ? -1 : 0; + return counter ? -1 : 0; } \ No newline at end of file diff --git a/src/common/tamq/tamq_conf.h b/src/common/tamq/tamq_conf.h index 1ed8a90..dc98011 100644 --- a/src/common/tamq/tamq_conf.h +++ b/src/common/tamq/tamq_conf.h @@ -2,8 +2,6 @@ #include "conf/config.h" - - // Set the URI to point to the IPAddress of your broker. // add any optional params to the url to enable things like // tightMarshalling or tcp logging etc. See the CMS web site for @@ -35,105 +33,106 @@ //============================================================ #define TAMQ_CONF_CLIENT_ACK_DEFAULT false -#define TAMQ_CONF_ADDR_KEY "amq_address" -#define TAMQ_CONF_CMD_URI_KEY "amq_cmd_uri" -#define TAMQ_CONF_RET_URI_KEY "amq_ret_uri" -#define TAMQ_CONF_LOG_URI_KEY "amq_log_uri" -#define TAMQ_CONF_USE_TOPICS_KEY "amq_use_topics" -#define TAMQ_CONF_CLIENT_ACK_KEY "amq_client_ack" - - -class TAMQ_Config: virtual public Config -{ - private: - int address_idx; /** IP of the ActiveMQ broker */ - int cmd_uri_idx; /** Topic/Queue for incoming commands */ - int ret_uri_idx; /** Topic/Queue for return messages */ - int log_uri_idx; /** Topic/Queue for logs */ - int use_topics_idx; /** Determines if topics will be used, rather than queues */ - int client_ack_idx; /** Determines if client will send ACK message, or if it will automatically be sent */ - - public: - TAMQ_Config(); - ~TAMQ_Config(); - - /** - * @brief Gets config for ActiveMQ broker address - * @returns config string on success, NULL on failure - */ - const char* GetBrokerAddress(); - - /** - * @brief Sets config for ActiveMQ broker address - * @param addr Broker address to set in config - * @returns 0 on success, -1 on failure - */ - int SetBrokerAddress(const char* addr); - - /** - * @brief Gets config for Command URI - * @returns config string on success, NULL on failure - */ - const char* GetCommandURI(); - - /** - * @brief Sets config for Command URI - * @param cmd_uri Command URI to set in config - * @returns 0 on success, -1 on failure - */ - int SetCommandURI(const char* cmd_uri); - - /** - * @brief Gets config for Returns URI - * @returns config string on success, NULL on failure - */ - const char* GetReturnsURI(); - - /** - * @brief Sets config for Returns URI - * @param ret_uri Returns URI to set in config - * @returns 0 on success, -1 on failure - */ - int SetReturnsURI(const char* ret_uri); - - /** - * @brief Gets config for Log URI - * @returns config string on success, NULL on failure - */ - const char* GetLogURI(); - - /** - * @brief Sets config for Log URI - * @param log_uri Log URI to set in config - * @returns 0 on success, -1 on failure - */ - int SetLogURI(const char* log_uri); - - /** - * @brief Gets config for Use Topics setting - * @returns config string on success, NULL on failure - */ - bool GetUseTopics(); - - /** - * @brief Sets config for Use Topics setting - * @param use_topics Set to true to use topics; Set to false to use queues - * @returns 0 on success, -1 on failure - */ - int SetUseTopics(bool use_topics); - - /** - * @brief Gets config for Client ACK setting - * @returns config string on success, NULL on failure - */ - bool GetClientAck(); - - /** - * @brief Sets config for Client ACK setting - * @param client_ack Set to true to have client manually ACK broker; Set to false to auto ACK broker - * @returns 0 on success, -1 on failure - */ - int SetClientAck(bool client_ack); - - int LoadDefaults(); +#define TAMQ_CONF_ADDR_KEY "amq_address" +#define TAMQ_CONF_CMD_URI_KEY "amq_cmd_uri" +#define TAMQ_CONF_RET_URI_KEY "amq_ret_uri" +#define TAMQ_CONF_LOG_URI_KEY "amq_log_uri" +#define TAMQ_CONF_USE_TOPICS_KEY "amq_use_topics" +#define TAMQ_CONF_CLIENT_ACK_KEY "amq_client_ack" + +class TAMQ_Config : virtual public Config { + private: + int address_idx; /** IP of the ActiveMQ broker */ + int cmd_uri_idx; /** Topic/Queue for incoming commands */ + int ret_uri_idx; /** Topic/Queue for return messages */ + int log_uri_idx; /** Topic/Queue for logs */ + int use_topics_idx; /** Determines if topics will be used, rather than queues + */ + int client_ack_idx; /** Determines if client will send ACK message, or if it + will automatically be sent */ + + public: + TAMQ_Config(); + ~TAMQ_Config(); + + /** + * @brief Gets config for ActiveMQ broker address + * @returns config string on success, NULL on failure + */ + const char *GetBrokerAddress(); + + /** + * @brief Sets config for ActiveMQ broker address + * @param addr Broker address to set in config + * @returns 0 on success, -1 on failure + */ + int SetBrokerAddress(const char *addr); + + /** + * @brief Gets config for Command URI + * @returns config string on success, NULL on failure + */ + const char *GetCommandURI(); + + /** + * @brief Sets config for Command URI + * @param cmd_uri Command URI to set in config + * @returns 0 on success, -1 on failure + */ + int SetCommandURI(const char *cmd_uri); + + /** + * @brief Gets config for Returns URI + * @returns config string on success, NULL on failure + */ + const char *GetReturnsURI(); + + /** + * @brief Sets config for Returns URI + * @param ret_uri Returns URI to set in config + * @returns 0 on success, -1 on failure + */ + int SetReturnsURI(const char *ret_uri); + + /** + * @brief Gets config for Log URI + * @returns config string on success, NULL on failure + */ + const char *GetLogURI(); + + /** + * @brief Sets config for Log URI + * @param log_uri Log URI to set in config + * @returns 0 on success, -1 on failure + */ + int SetLogURI(const char *log_uri); + + /** + * @brief Gets config for Use Topics setting + * @returns config string on success, NULL on failure + */ + bool GetUseTopics(); + + /** + * @brief Sets config for Use Topics setting + * @param use_topics Set to true to use topics; Set to false to use queues + * @returns 0 on success, -1 on failure + */ + int SetUseTopics(bool use_topics); + + /** + * @brief Gets config for Client ACK setting + * @returns config string on success, NULL on failure + */ + bool GetClientAck(); + + /** + * @brief Sets config for Client ACK setting + * @param client_ack Set to true to have client manually ACK broker; Set to + * false to auto ACK broker + * @returns 0 on success, -1 on failure + */ + int SetClientAck(bool client_ack); + + int LoadDefaults(); }; \ No newline at end of file diff --git a/src/common/tamq/tamq_sub.cpp b/src/common/tamq/tamq_sub.cpp index 7388349..9019928 100644 --- a/src/common/tamq/tamq_sub.cpp +++ b/src/common/tamq/tamq_sub.cpp @@ -15,216 +15,204 @@ * limitations under the License. */ -#include -#include -#include -#include +#include "tamq/tamq_sub.h" + #include -#include +#include #include -#include +#include #include -#include -#include -#include -#include #include -#include +#include #include +#include #include -#include +#include +#include +#include +#include +#include +#include +#include #include +#include + #include -#include "tamq/tamq_sub.h" -#include "sub/sub.h" #include "log/log.h" -#include "util/comm.h" +#include "sub/sub.h" #include "util/array.h" +#include "util/comm.h" -#define LOG_FILE_THRESHOLD_THIS LOG_THRESHOLD_MAX -#define LOG_CONSOLE_THRESHOLD_THIS LOG_THRESHOLD_DEFAULT +#define LOG_FILE_THRESHOLD_THIS LOG_THRESHOLD_MAX +#define LOG_CONSOLE_THRESHOLD_THIS LOG_THRESHOLD_DEFAULT // Globally declare cleint variable TAMQ_Consumer *client; static int counter = 0; -TAMQ_Consumer::TAMQ_Consumer( const std::string& brokerURI, - const std::string& destURI, - bool useTopic, - bool clientAck) : - connection(NULL), - session(NULL), - destination(NULL), - consumer(NULL), - useTopic(useTopic), - brokerURI(brokerURI), - destURI(destURI), - clientAck(clientAck) - { - LOG_VERBOSE(4, "TAMQ Broker Address: %s", brokerURI.c_str()); - LOG_VERBOSE(4, "TAMQ Command URI: %s", destURI.c_str()); - LOG_VERBOSE(4, "TAMQ Use Topics: %s", useTopic ? "true" : "false"); - LOG_VERBOSE(4, "TAMQ Client ACK: %s", clientAck ? "true" : "false"); - - if (0 == counter++) - { - activemq::library::ActiveMQCPP::initializeLibrary(); - } - } +TAMQ_Consumer::TAMQ_Consumer(const std::string &brokerURI, + const std::string &destURI, bool useTopic, + bool clientAck) + : connection(NULL), + session(NULL), + destination(NULL), + consumer(NULL), + useTopic(useTopic), + brokerURI(brokerURI), + destURI(destURI), + clientAck(clientAck) { + LOG_VERBOSE(4, "TAMQ Broker Address: %s", brokerURI.c_str()); + LOG_VERBOSE(4, "TAMQ Command URI: %s", destURI.c_str()); + LOG_VERBOSE(4, "TAMQ Use Topics: %s", useTopic ? "true" : "false"); + LOG_VERBOSE(4, "TAMQ Client ACK: %s", clientAck ? "true" : "false"); + + if (0 == counter++) { + activemq::library::ActiveMQCPP::initializeLibrary(); + } +} TAMQ_Consumer::~TAMQ_Consumer() { - if (0 == --counter) - { - activemq::library::ActiveMQCPP::shutdownLibrary(); - } + if (0 == --counter) { + activemq::library::ActiveMQCPP::shutdownLibrary(); + } } -void TAMQ_Consumer::close() { - this->cleanup(); -} +void TAMQ_Consumer::close() { this->cleanup(); } -void TAMQ_Consumer::runConsumer() -{ - try { +void TAMQ_Consumer::runConsumer() { + try { + // Create a ConnectionFactory + activemq::core::ActiveMQConnectionFactory *connectionFactory = + new activemq::core::ActiveMQConnectionFactory(brokerURI); - // Create a ConnectionFactory - activemq::core::ActiveMQConnectionFactory* connectionFactory = - new activemq::core::ActiveMQConnectionFactory( brokerURI ); + // Create a Connection + connection = connectionFactory->createConnection(); + delete connectionFactory; - // Create a Connection - connection = connectionFactory->createConnection(); - delete connectionFactory; + activemq::core::ActiveMQConnection *amqConnection = + dynamic_cast(connection); + if (amqConnection != NULL) { + amqConnection->addTransportListener(this); + } - activemq::core::ActiveMQConnection* amqConnection = dynamic_cast( connection ); - if( amqConnection != NULL ) { - amqConnection->addTransportListener( this ); - } + connection->start(); - connection->start(); + connection->setExceptionListener(this); - connection->setExceptionListener(this); + // Create a Session + if (clientAck) { + session = connection->createSession(cms::Session::CLIENT_ACKNOWLEDGE); + } else { + session = connection->createSession(cms::Session::AUTO_ACKNOWLEDGE); + } - // Create a Session - if( clientAck ) { - session = connection->createSession( cms::Session::CLIENT_ACKNOWLEDGE ); - } else { - session = connection->createSession( cms::Session::AUTO_ACKNOWLEDGE ); - } + // Create the destination (Topic or Queue) + if (useTopic) { + destination = session->createTopic(destURI); + } else { + destination = session->createQueue(destURI); + } + + // Create a MessageConsumer from the Session to the Topic or Queue + consumer = session->createConsumer(destination); + consumer->setMessageListener(this); + + } catch (cms::CMSException &e) { + e.printStackTrace(); + } +} + +void TAMQ_Consumer::onMessage(const cms::Message *message) { + LOG_VERBOSE(2, "Received Message"); + int length = 0; - // Create the destination (Topic or Queue) - if( useTopic ) { - destination = session->createTopic( destURI ); - } else { - destination = session->createQueue( destURI ); - } + try { + SUB_Buffer *buf = sub->DequeueBuffer(SUB_QUEUE_FREE); + if (!buf) STD_FAIL_VOID; - // Create a MessageConsumer from the Session to the Topic or Queue - consumer = session->createConsumer( destination ); - consumer->setMessageListener( this ); + const cms::BytesMessage *textMessage = + dynamic_cast(message); - } catch (cms::CMSException& e) { - e.printStackTrace(); + if (textMessage != NULL) { + length = textMessage->getBodyLength(); + memcpy(&buf->body, textMessage->getBodyBytes(), length); + } else { + length = 6; + memcpy(&buf->body, "ERROR", length); } -} -void TAMQ_Consumer::onMessage( const cms::Message* message ) -{ - LOG_VERBOSE(2, "Received Message"); - int length = 0; - - try - { - SUB_Buffer *buf = sub->DequeueBuffer (SUB_QUEUE_FREE); - if (!buf) STD_FAIL_VOID; - - const cms::BytesMessage* textMessage = - dynamic_cast< const cms::BytesMessage* >( message ); - - if( textMessage != NULL ) { - length = textMessage->getBodyLength(); - memcpy(&buf->body, textMessage->getBodyBytes(), length); - } else { - length = 6; - memcpy(&buf->body, "ERROR", length); - } - - buf->len = length; - - if( clientAck ) { - message->acknowledge(); - } - - #if LOG_CONSOLE_THRESHOLD_THIS >= LOG_VERBOSE + 6 | LOG_CONSOLE_THRESHOLD_THIS >= LOG_VERBOSE + 6 - char text[length * 6 + 5]; - sprintf(&text[0], "INIT"); - uint16_t str_iter = 0; - for (uint16_t iter = 0; iter < length; iter++) - { - str_iter += sprintf(&text[str_iter], "0x%02X, ", buf->body[iter]); - } - - LOG_VERBOSE(6, "Message : %d", length); - #endif - - sub->EnqueueBuffer(SUB_QUEUE_COMMAND, buf); + buf->len = length; + + if (clientAck) { + message->acknowledge(); } - catch (cms::CMSException& e) - { - e.printStackTrace(); +#if LOG_CONSOLE_THRESHOLD_THIS >= LOG_VERBOSE + 6 | \ + LOG_CONSOLE_THRESHOLD_THIS >= LOG_VERBOSE + 6 + char text[length * 6 + 5]; + sprintf(&text[0], "INIT"); + uint16_t str_iter = 0; + for (uint16_t iter = 0; iter < length; iter++) { + str_iter += sprintf(&text[str_iter], "0x%02X, ", buf->body[iter]); } + + LOG_VERBOSE(6, "Message : %d", length); +#endif + + sub->EnqueueBuffer(SUB_QUEUE_COMMAND, buf); + } + + catch (cms::CMSException &e) { + e.printStackTrace(); + } } -void TAMQ_Consumer::onException( const cms::CMSException& ex AMQCPP_UNUSED ) { - LOG_ERROR("CMS Exception occurred. Shutting down client.\n"); - exit(1); +void TAMQ_Consumer::onException(const cms::CMSException &ex AMQCPP_UNUSED) { + LOG_ERROR("CMS Exception occurred. Shutting down client.\n"); + exit(1); } void TAMQ_Consumer::transportInterrupted() { - LOG_INFO("The Connection's Transport has been Interrupted."); + LOG_INFO("The Connection's Transport has been Interrupted."); } void TAMQ_Consumer::transportResumed() { - LOG_INFO("The Connection's Transport has been Restored."); + LOG_INFO("The Connection's Transport has been Restored."); } -int TAMQ_Consumer::Start() -{ - runConsumer(); // Start it up and it will listen forever. - LOG_INFO("Talos ActiveMQ Client Running..."); +int TAMQ_Consumer::Start() { + runConsumer(); // Start it up and it will listen forever. + LOG_INFO("Talos ActiveMQ Client Running..."); - return 0; + return 0; } -int TAMQ_Consumer::Stop() -{ - // All CMS resources should be closed before the library is shutdown. - close(); - LOG_INFO("Talos ActiveMQ Client Stopped"); +int TAMQ_Consumer::Stop() { + // All CMS resources should be closed before the library is shutdown. + close(); + LOG_INFO("Talos ActiveMQ Client Stopped"); - return 0; + return 0; } -int TAMQ_Consumer::RegisterSubscriber(Subscriber* sub) -{ - if (!sub) STD_FAIL; - this->sub = sub; - return 0; +int TAMQ_Consumer::RegisterSubscriber(Subscriber *sub) { + if (!sub) STD_FAIL; + this->sub = sub; + return 0; } -void TAMQ_Consumer::cleanup(){ - - try { - if( connection != NULL ) { - connection->close(); - } - } catch ( cms::CMSException& e ) { - e.printStackTrace(); +void TAMQ_Consumer::cleanup() { + try { + if (connection != NULL) { + connection->close(); } - - delete destination; - delete consumer; - delete session; - delete connection; + } catch (cms::CMSException &e) { + e.printStackTrace(); + } + + delete destination; + delete consumer; + delete session; + delete connection; } \ No newline at end of file diff --git a/src/common/tamq/tamq_sub.h b/src/common/tamq/tamq_sub.h index e0248ee..7dd2ef8 100644 --- a/src/common/tamq/tamq_sub.h +++ b/src/common/tamq/tamq_sub.h @@ -1,105 +1,105 @@ /** - * (Talos) ActiveMQ implementation (TAMQ to avoid confusion with the Apache library) - * Implementation of the Subscriber interface -*/ + * (Talos) ActiveMQ implementation (TAMQ to avoid confusion with the Apache + * library) Implementation of the Subscriber interface + */ #pragma once -#include -#include -#include -#include #include -#include +#include #include -#include +#include #include -#include -#include -#include -#include #include -#include +#include #include +#include #include -#include +#include +#include +#include +#include +#include +#include +#include #include +#include + #include #include -#include "util/comm.h" #include "sub/sub.h" +#include "util/comm.h" #define TAMQ_CONFIG_FIELD_LEN 64 /** Talos ActiveMQ specific configurations */ -typedef struct _tamq_config -{ - char connection[TAMQ_CONFIG_FIELD_LEN]; /** The IPv4 Address and port of the broker (e.g. 'failover:(tcp://127.0.0.1:61616)') */ - char dest_uri[TAMQ_CONFIG_FIELD_LEN]; /** The name of the topic/queue the client will listen to */ - bool use_topics; /** When true, TAMQ will consume from a topic, rather than a queue */ - bool client_ack; /** When true, TAMQ will not automatically send back an ack after consuming a message from the broker. */ +typedef struct _tamq_config { + char connection + [TAMQ_CONFIG_FIELD_LEN]; /** The IPv4 Address and port of the broker (e.g. + 'failover:(tcp://127.0.0.1:61616)') */ + char dest_uri[TAMQ_CONFIG_FIELD_LEN]; /** The name of the topic/queue the + client will listen to */ + bool use_topics; /** When true, TAMQ will consume from a topic, rather than a + queue */ + bool client_ack; /** When true, TAMQ will not automatically send back an ack + after consuming a message from the broker. */ } TAMQ_Configuration; /** ID numbers of various AMQ message types */ -typedef enum _tamq_message_type -{ - ID_ACTIVEMQBLOBMESSAGE = 29, - ID_ACTIVEMQBYTESMESSAGE = 24, - ID_ACTIVEMQMAPMESSAGE = 25, - ID_ACTIVEMQMESSAGE = 23, - ID_ACTIVEMQOBJECTMESSAGE = 26, - ID_ACTIVEMQSTREAMMESSAGE = 27, - ID_ACTIVEMQTEXTMESSAGE = 28, +typedef enum _tamq_message_type { + ID_ACTIVEMQBLOBMESSAGE = 29, + ID_ACTIVEMQBYTESMESSAGE = 24, + ID_ACTIVEMQMAPMESSAGE = 25, + ID_ACTIVEMQMESSAGE = 23, + ID_ACTIVEMQOBJECTMESSAGE = 26, + ID_ACTIVEMQSTREAMMESSAGE = 27, + ID_ACTIVEMQTEXTMESSAGE = 28, } Tamq_Message_Type; //////////////////////////////////////////////////////////////////////////////// -class TAMQ_Consumer : public cms::ExceptionListener, - public cms::MessageListener, - public activemq::transport::DefaultTransportListener, - public Inbox -{ - private: - - cms::Connection* connection; - cms::Session* session; - cms::Destination* destination; - cms::MessageConsumer* consumer; - bool useTopic; - std::string brokerURI; // IP Addr/Port to broker - std::string destURI; // Topic/Queue name - bool clientAck; +class TAMQ_Consumer : public cms::ExceptionListener, + public cms::MessageListener, + public activemq::transport::DefaultTransportListener, + public Inbox { + private: + cms::Connection *connection; + cms::Session *session; + cms::Destination *destination; + cms::MessageConsumer *consumer; + bool useTopic; + std::string brokerURI; // IP Addr/Port to broker + std::string destURI; // Topic/Queue name + bool clientAck; - private: - TAMQ_Consumer( const TAMQ_Consumer& ); + private: + TAMQ_Consumer(const TAMQ_Consumer &); - public: - TAMQ_Consumer& operator= ( const TAMQ_Consumer& ); - TAMQ_Consumer( const std::string& brokerURI, - const std::string& destURI, - bool useTopic = false, - bool clientAck = false ); + public: + TAMQ_Consumer &operator=(const TAMQ_Consumer &); + TAMQ_Consumer(const std::string &brokerURI, const std::string &destURI, + bool useTopic = false, bool clientAck = false); - /** - * The close method must be run before destructor - */ - ~TAMQ_Consumer(); - void close(); - void runConsumer(); + /** + * The close method must be run before destructor + */ + ~TAMQ_Consumer(); + void close(); + void runConsumer(); - // Called from the consumer since this class is a registered MessageListener. - virtual void onMessage( const cms::Message* message ); + // Called from the consumer since this class is a registered MessageListener. + virtual void onMessage(const cms::Message *message); - // If something bad happens you see it here as this class is also been - // registered as an ExceptionListener with the connection. - virtual void onException( const cms::CMSException& ex AMQCPP_UNUSED ); - virtual void transportInterrupted(); - virtual void transportResumed(); - int Start(); - int Stop(); - int RegisterSubscriber(Subscriber* sub); + // If something bad happens you see it here as this class is also been + // registered as an ExceptionListener with the connection. + virtual void onException(const cms::CMSException &ex AMQCPP_UNUSED); + virtual void transportInterrupted(); + virtual void transportResumed(); + int Start(); + int Stop(); + int RegisterSubscriber(Subscriber *sub); - private: - void cleanup(); + private: + void cleanup(); }; //////////////////////////////////////////////////////////////////////////////// \ No newline at end of file diff --git a/src/common/tmp/tests/tmp_test.cpp b/src/common/tmp/tests/tmp_test.cpp index 91fd3a5..0666359 100644 --- a/src/common/tmp/tests/tmp_test.cpp +++ b/src/common/tmp/tests/tmp_test.cpp @@ -1,27 +1,22 @@ // CPPUTEST testing module -#include "CppUTest/TestHarness.h" #include "tmp/tmp.h" -TEST_GROUP(FirstTestGroup) -{ -}; +#include "CppUTest/TestHarness.h" + +TEST_GROUP(FirstTestGroup){}; -TEST(FirstTestGroup, FirstTest) -{ - //noop +TEST(FirstTestGroup, FirstTest) { + // noop } -TEST(FirstTestGroup, SecondTest) -{ - int i = -16; - for (; i < 0; i++) - { - CHECK_EQUAL(-1, test(i)); - } +TEST(FirstTestGroup, SecondTest) { + int i = -16; + for (; i < 0; i++) { + CHECK_EQUAL(-1, test(i)); + } - for (; i < 16; i++) - { - CHECK_EQUAL(i, test(i)); - } + for (; i < 16; i++) { + CHECK_EQUAL(i, test(i)); + } } \ No newline at end of file diff --git a/src/common/tmp/tmp.cpp b/src/common/tmp/tmp.cpp index 544c5b7..0d1224b 100644 --- a/src/common/tmp/tmp.cpp +++ b/src/common/tmp/tmp.cpp @@ -1,7 +1,6 @@ #include -int8_t test (int8_t arg) -{ - if (arg < 0) return -1; - return arg; +int8_t test(int8_t arg) { + if (arg < 0) return -1; + return arg; } \ No newline at end of file diff --git a/src/common/tmp/tmp.h b/src/common/tmp/tmp.h index 3cb59cd..5c88466 100644 --- a/src/common/tmp/tmp.h +++ b/src/common/tmp/tmp.h @@ -2,4 +2,4 @@ #include -int8_t test (int8_t arg); \ No newline at end of file +int8_t test(int8_t arg); \ No newline at end of file diff --git a/src/common/util/array.h b/src/common/util/array.h index 13230f9..6b75bfa 100644 --- a/src/common/util/array.h +++ b/src/common/util/array.h @@ -1,6 +1,6 @@ /** * Array helper functions -*/ + */ #pragma once @@ -10,7 +10,7 @@ #include "util/comm.h" #define UTIL_len(arr) (sizeof(arr) / sizeof(arr[0])) -#define UTIL_modulo(a,b) (((a%b) + b) % b) +#define UTIL_modulo(a, b) (((a % b) + b) % b) #define STRLEN(s) sizeof(s) #define UTIL_BYTE_FMT "0x%02X, " #define UTIL_BYTE_FMT_LEN 6 @@ -18,8 +18,9 @@ /** * @brief Returns the length of a formated byte-string * @param len Length of byte source - * @returns Length of C String requried to hold formated byte array on success, -1 on failure -*/ + * @returns Length of C String requried to hold formated byte array on success, + * -1 on failure + */ #define UTIL_BYTE_STR_FMT_LEN(len) (len * UTIL_BYTE_FMT_LEN + 1) /** @@ -28,15 +29,14 @@ * @param src Pointer to byte source * @param len Length of byte source * @returns 0 on success, -1 on failure -*/ -inline int UTIL_format_byte_str(char *dst, const uint8_t *src, uint16_t len) -{ - if (!dst || !src) return -1; + */ +inline int UTIL_format_byte_str(char *dst, const uint8_t *src, uint16_t len) { + if (!dst || !src) return -1; - sprintf(dst, "INIT"); - uint16_t str_iter = 0; - for (uint16_t iter = 0; iter < len; iter++) - str_iter += sprintf(&dst[str_iter], UTIL_BYTE_FMT, src[iter]); + sprintf(dst, "INIT"); + uint16_t str_iter = 0; + for (uint16_t iter = 0; iter < len; iter++) + str_iter += sprintf(&dst[str_iter], UTIL_BYTE_FMT, src[iter]); - return 0; + return 0; } \ No newline at end of file diff --git a/src/common/util/comm.h b/src/common/util/comm.h index 43f2f1c..ca8ad42 100644 --- a/src/common/util/comm.h +++ b/src/common/util/comm.h @@ -1,10 +1,22 @@ /** * A file containing useful values/shortcuts -*/ + */ #pragma once #include "log/log.h" -#define STD_FAIL {LOG_IEC(); return -1;} // Not quite sure where to put this -#define STD_FAIL_VOID {LOG_IEC(); return;} // Not quite sure where to put this -#define STD_FAIL_VOID_PTR {LOG_IEC(); return NULL;} // Not quite sure where to put this \ No newline at end of file +#define STD_FAIL \ + { \ + LOG_IEC(); \ + return -1; \ + } // Not quite sure where to put this +#define STD_FAIL_VOID \ + { \ + LOG_IEC(); \ + return; \ + } // Not quite sure where to put this +#define STD_FAIL_VOID_PTR \ + { \ + LOG_IEC(); \ + return NULL; \ + } // Not quite sure where to put this diff --git a/src/common/util/time.h b/src/common/util/time.h index c7d4a87..a2a6aaf 100644 --- a/src/common/util/time.h +++ b/src/common/util/time.h @@ -1,9 +1,9 @@ #include #include -static inline uint16_t tval_diff_ms(struct timeval* end, struct timeval* start) -{ - time_t start_ms = (start->tv_sec * 1000) + (start->tv_usec / 1000); - time_t end_ms = (end->tv_sec * 1000) + (end->tv_usec / 1000); - return end_ms - start_ms; +static inline uint16_t tval_diff_ms(struct timeval *end, + struct timeval *start) { + time_t start_ms = (start->tv_sec * 1000) + (start->tv_usec / 1000); + time_t end_ms = (end->tv_sec * 1000) + (end->tv_usec / 1000); + return end_ms - start_ms; } diff --git a/src/common/util/timestamp.c b/src/common/util/timestamp.c index 0d76c9b..8bbbbb7 100644 --- a/src/common/util/timestamp.c +++ b/src/common/util/timestamp.c @@ -1,217 +1,191 @@ #include "util/timestamp.h" #include -#include #include -#include +#include #include +#include #include "log/log.h" #include "util/array.h" -//NOTE: can't use debug logs: logs use timestamps +// NOTE: can't use debug logs: logs use timestamps -int8_t UTIL_time_iso8601_datestamp_UTC(char* dst_str, time_t time) -{ - if (!dst_str) - { - return -1; - } +int8_t UTIL_time_iso8601_datestamp_UTC(char* dst_str, time_t time) { + if (!dst_str) { + return -1; + } - struct tm *ftime = gmtime(&time); - size_t ret = strftime(dst_str, UTIL_DATESTAMP_LEN, UTIL_DATESTAMP, ftime); - return ret == 0 ? (size_t) -1 : ret; + struct tm* ftime = gmtime(&time); + size_t ret = strftime(dst_str, UTIL_DATESTAMP_LEN, UTIL_DATESTAMP, ftime); + return ret == 0 ? (size_t)-1 : ret; } -int8_t UTIL_time_iso8601_datestamp_local(char* dst_str, time_t time) -{ - if (!dst_str) - { - return -1; - } +int8_t UTIL_time_iso8601_datestamp_local(char* dst_str, time_t time) { + if (!dst_str) { + return -1; + } - struct tm *ftime = localtime(&time); - size_t ret = strftime(dst_str, UTIL_DATESTAMP_LEN, UTIL_DATESTAMP, ftime); - return ret == 0 ? (size_t) -1 : ret; + struct tm* ftime = localtime(&time); + size_t ret = strftime(dst_str, UTIL_DATESTAMP_LEN, UTIL_DATESTAMP, ftime); + return ret == 0 ? (size_t)-1 : ret; } -int8_t UTIL_time_iso8601_timestamp_UTC(char* dst_str, time_t time) -{ - if (!dst_str) - { - return -1; - } +int8_t UTIL_time_iso8601_timestamp_UTC(char* dst_str, time_t time) { + if (!dst_str) { + return -1; + } - struct tm *ftime = gmtime(&time); - size_t ret = strftime(dst_str, UTIL_TIMESTAMP_LEN, UTIL_TIMESTAMP, ftime); - return ret == 0 ? (size_t) -1 : ret; + struct tm* ftime = gmtime(&time); + size_t ret = strftime(dst_str, UTIL_TIMESTAMP_LEN, UTIL_TIMESTAMP, ftime); + return ret == 0 ? (size_t)-1 : ret; } -int8_t UTIL_time_iso8601_timestamp_local(char* dst_str, time_t time) -{ - if (!dst_str) - { - return -1; - } - - struct tm *ftime = localtime(&time); - size_t ret = strftime(dst_str, UTIL_TIMESTAMP_LEN, UTIL_TIMESTAMP, ftime); - return ret == 0 ? (size_t) -1 : ret; +int8_t UTIL_time_iso8601_timestamp_local(char* dst_str, time_t time) { + if (!dst_str) { + return -1; + } + + struct tm* ftime = localtime(&time); + size_t ret = strftime(dst_str, UTIL_TIMESTAMP_LEN, UTIL_TIMESTAMP, ftime); + return ret == 0 ? (size_t)-1 : ret; } -int8_t UTIL_time_msec_timestamp(char* dst_str, __useconds_t usec) -{ - if (!dst_str) - { - return -1; - } +int8_t UTIL_time_msec_timestamp(char* dst_str, __useconds_t usec) { + if (!dst_str) { + return -1; + } - size_t ret = snprintf(dst_str, UTIL_TS_MSEC_LEN, UTIL_TS_MSEC, (usec / 1000) % 1000); - return ret == 0 ? (size_t) -1 : ret; + size_t ret = + snprintf(dst_str, UTIL_TS_MSEC_LEN, UTIL_TS_MSEC, (usec / 1000) % 1000); + return ret == 0 ? (size_t)-1 : ret; } -int8_t UTIL_time_msec_usec_timestamp(char* dst_str, __useconds_t usec) -{ - if (!dst_str) - { - return -1; - } +int8_t UTIL_time_msec_usec_timestamp(char* dst_str, __useconds_t usec) { + if (!dst_str) { + return -1; + } - size_t ret = snprintf(dst_str, UTIL_TS_MSEC_LEN * 2, UTIL_TS_MSEC UTIL_TS_MSEC, (usec / 1000) % 1000, usec % 1000); - return ret == 0 ? (size_t) -1 : ret; + size_t ret = + snprintf(dst_str, UTIL_TS_MSEC_LEN * 2, UTIL_TS_MSEC UTIL_TS_MSEC, + (usec / 1000) % 1000, usec % 1000); + return ret == 0 ? (size_t)-1 : ret; } -int8_t UTIL_time_iso8601_time_offset(char* dst_str, int16_t tz_offset_sec) -{ - if (!dst_str) - { - return -1; - } +int8_t UTIL_time_iso8601_time_offset(char* dst_str, int16_t tz_offset_sec) { + if (!dst_str) { + return -1; + } - tz_offset_sec %= 24 * 60 * 60; // Wrap offsets greater than 24 hours - size_t ret = snprintf(dst_str, UTIL_TS_OFFSET_LEN, UTIL_TS_OFFSET, tz_offset_sec / (60 * 60), (tz_offset_sec / 60) % 60); - return ret == 0 ? (size_t) -1 : ret; + tz_offset_sec %= 24 * 60 * 60; // Wrap offsets greater than 24 hours + size_t ret = snprintf(dst_str, UTIL_TS_OFFSET_LEN, UTIL_TS_OFFSET, + tz_offset_sec / (60 * 60), (tz_offset_sec / 60) % 60); + return ret == 0 ? (size_t)-1 : ret; } -static int8_t iso8601_complete_datetime_UTC(char* dst_str, time_t time) -{ - if (!dst_str) - { - return -1; - } - - char* str_iter = dst_str; - size_t ret; - - ret = UTIL_time_iso8601_datestamp_UTC(str_iter, time); - if (ret == 0) - { - return -1; - } - str_iter += ret; - - ret = UTIL_time_iso8601_timestamp_UTC(str_iter, time); - if (ret == 0) - { - return -1; - } - str_iter += ret; - return str_iter - dst_str; +static int8_t iso8601_complete_datetime_UTC(char* dst_str, time_t time) { + if (!dst_str) { + return -1; + } + + char* str_iter = dst_str; + size_t ret; + + ret = UTIL_time_iso8601_datestamp_UTC(str_iter, time); + if (ret == 0) { + return -1; + } + str_iter += ret; + + ret = UTIL_time_iso8601_timestamp_UTC(str_iter, time); + if (ret == 0) { + return -1; + } + str_iter += ret; + return str_iter - dst_str; } -static int8_t iso8601_complete_datetime_local(char* dst_str, time_t time) -{ - if (!dst_str) - { - return -1; - } - - char* str_iter = dst_str; - int8_t ret; - - ret = UTIL_time_iso8601_datestamp_local(str_iter, time); - if (ret == -1) - { - return -1; - } - str_iter += ret; - - ret = UTIL_time_iso8601_timestamp_local(str_iter, time); - if (ret == -1) - { - return -1; - } - str_iter += ret; - return str_iter - dst_str; +static int8_t iso8601_complete_datetime_local(char* dst_str, time_t time) { + if (!dst_str) { + return -1; + } + + char* str_iter = dst_str; + int8_t ret; + + ret = UTIL_time_iso8601_datestamp_local(str_iter, time); + if (ret == -1) { + return -1; + } + str_iter += ret; + + ret = UTIL_time_iso8601_timestamp_local(str_iter, time); + if (ret == -1) { + return -1; + } + str_iter += ret; + return str_iter - dst_str; } -int8_t UTIL_time_iso8601_complete_datetime_UTC(char* dst_str, time_t time) -{ - char* str_iter = dst_str; - int8_t ret = iso8601_complete_datetime_UTC(str_iter, time); - if (ret == -1) - { - return -1; - } - str_iter += ret; - - str_iter += sprintf(str_iter, "Z"); - return str_iter - dst_str; +int8_t UTIL_time_iso8601_complete_datetime_UTC(char* dst_str, time_t time) { + char* str_iter = dst_str; + int8_t ret = iso8601_complete_datetime_UTC(str_iter, time); + if (ret == -1) { + return -1; + } + str_iter += ret; + + str_iter += sprintf(str_iter, "Z"); + return str_iter - dst_str; } -int8_t UTIL_time_iso8601_complete_datetime_local(char* dst_str, time_t time) -{ - char* str_iter = dst_str; - int8_t ret = iso8601_complete_datetime_local(str_iter, time); - if (ret == -1) - { - return -1; - } - str_iter += ret; - - struct tm *ftime = localtime(&time); - str_iter += UTIL_time_iso8601_time_offset(str_iter, ftime->tm_gmtoff); - return str_iter - dst_str; +int8_t UTIL_time_iso8601_complete_datetime_local(char* dst_str, time_t time) { + char* str_iter = dst_str; + int8_t ret = iso8601_complete_datetime_local(str_iter, time); + if (ret == -1) { + return -1; + } + str_iter += ret; + + struct tm* ftime = localtime(&time); + str_iter += UTIL_time_iso8601_time_offset(str_iter, ftime->tm_gmtoff); + return str_iter - dst_str; } -int8_t UTIL_time_iso8601_complete_datetime_msec_UTC(char* dst_str, time_t time) -{ - char* str_iter = dst_str; - int8_t ret = iso8601_complete_datetime_UTC(str_iter, time); - if (ret == -1) - { - return -1; - } - str_iter += ret; - - ret = UTIL_time_msec_timestamp(str_iter, time); - if (ret == -1) - { - return -1; - } - str_iter += ret; - - str_iter += sprintf(str_iter, "Z"); - return str_iter - dst_str; +int8_t UTIL_time_iso8601_complete_datetime_msec_UTC(char* dst_str, + time_t time) { + char* str_iter = dst_str; + int8_t ret = iso8601_complete_datetime_UTC(str_iter, time); + if (ret == -1) { + return -1; + } + str_iter += ret; + + ret = UTIL_time_msec_timestamp(str_iter, time); + if (ret == -1) { + return -1; + } + str_iter += ret; + + str_iter += sprintf(str_iter, "Z"); + return str_iter - dst_str; } -int8_t UTIL_time_iso8601_complete_datetime_msec_local(char* dst_str, time_t time) -{ - char* str_iter = dst_str; - int8_t ret = iso8601_complete_datetime_local(str_iter, time); - if (ret == -1) - { - return -1; - } - str_iter += ret; - - ret = UTIL_time_msec_timestamp(str_iter, time); - if (ret == -1) - { - return -1; - } - str_iter += ret; - - struct tm *ftime = localtime(&time); - str_iter += UTIL_time_iso8601_time_offset(str_iter, ftime->tm_gmtoff); - return str_iter - dst_str; +int8_t UTIL_time_iso8601_complete_datetime_msec_local(char* dst_str, + time_t time) { + char* str_iter = dst_str; + int8_t ret = iso8601_complete_datetime_local(str_iter, time); + if (ret == -1) { + return -1; + } + str_iter += ret; + + ret = UTIL_time_msec_timestamp(str_iter, time); + if (ret == -1) { + return -1; + } + str_iter += ret; + + struct tm* ftime = localtime(&time); + str_iter += UTIL_time_iso8601_time_offset(str_iter, ftime->tm_gmtoff); + return str_iter - dst_str; } \ No newline at end of file diff --git a/src/common/util/timestamp.h b/src/common/util/timestamp.h index 46c112c..1df2882 100644 --- a/src/common/util/timestamp.h +++ b/src/common/util/timestamp.h @@ -2,146 +2,154 @@ * Timestamping Module * Used for converting time_t structs into ISO8601 timestamps * Supports local timezones, UTC/Zulu timezone, and optionally milliseconds -*/ + */ #pragma once #include -#include #include +#include #ifdef __cplusplus extern "C" { #endif // ISO 6801 -#define UTIL_DATESTAMP "%F" - // YYYY-MM-DD -#define UTIL_DATESTAMP_LEN (10+1) - -#define UTIL_TIMESTAMP "T%T" - // THH:MM:SS -#define UTIL_TIMESTAMP_LEN (1+(2*3)+2+1) - -#define UTIL_TS_OFFSET "%+02d:%02d" - // +TH:TS -#define UTIL_TS_OFFSET_LEN (1+2+1+2+1) - -#define UTIL_TS_MSEC ":%03d" // Also used for usec - // :mmm -#define UTIL_TS_MSEC_LEN (1+3+1) +#define UTIL_DATESTAMP "%F" +// YYYY-MM-DD +#define UTIL_DATESTAMP_LEN (10 + 1) + +#define UTIL_TIMESTAMP "T%T" +// THH:MM:SS +#define UTIL_TIMESTAMP_LEN (1 + (2 * 3) + 2 + 1) + +#define UTIL_TS_OFFSET "%+02d:%02d" +// +TH:TS +#define UTIL_TS_OFFSET_LEN (1 + 2 + 1 + 2 + 1) + +#define UTIL_TS_MSEC \ + ":%03d" // Also used for usec + // :mmm +#define UTIL_TS_MSEC_LEN (1 + 3 + 1) // #define UTIL_TS_USEC UTIL_TIMESTAMP_MSEC UTIL_TIMESTAMP_MSEC // #define UTIL_TS_USEC_LEN (2 * UTIL_TIMESTAMP_MSEC_LEN) // #define UTIL_TS_ISO6801_Z UTIL_TIMESTAMP "Z" // #define UTIL_TS_ISO6801_Z_LEN (UTIL_TIMESTAMP_LEN + 1) // #define UTIL_TS_ISO6801 UTIL_TIMESTAMP UTIL_OFFSET -// #define UTIL_TS_ISO6801_LEN (UTIL_TIMESTAMP_LEN + UTIL_OFFSET_LEN) -// #define UTIL_TS_ISO6801_MSEC UTIL_TS_ISO6801 UTIL_TS_MSEC -// #define UTIL_TS_ISO6801_LEN (UTIL_TS_ISO6801_LEN + UTIL_TS_MSEC_LEN) -// #define UTIL_TS_ISO6801_USEC UTIL_TS_ISO6801_MSEC UTIL_TS_MSEC -// #define UTIL_TS_ISO6801_LEN (UTIL_TS_ISO6801_MSEC_LEN + UTIL_TS_MSEC_LEN) - -// #define UTIL_DTS_ISO6801_Z UTIL_DATESTAMP UTIL_TS_ISO6801_Z -// #define UTIL_DTS_ISO6801_Z_LEN (UTIL_DATESTAMP_LEN + UTIL_TS_ISO6801_Z_LEN) -// #define UTIL_DTS_ISO6801 UTIL_DATESTAMP UTIL_TS_ISO6801 -// #define UTIL_DTS_ISO6801_LEN (UTIL_DATESTAMP_LEN + UTIL_TS_ISO6801_LEN) -// #define UTIL_DTS_ISO6801_MSEC UTIL_DATESTAMP UTIL_TS_ISO6801_MSEC -// #define UTIL_DTS_ISO6801_LEN (UTIL_DATESTAMP_LEN + UTIL_TS_ISO6801_LEN) -// #define UTIL_DTS_ISO6801_USEC UTIL_DATESTAMP UTIL_TS_ISO6801_USEC -// #define UTIL_DTS_ISO6801_LEN (UTIL_DATESTAMP_LEN + UTIL_TS_ISO6801_LEN) - - +// #define UTIL_TS_ISO6801_LEN (UTIL_TIMESTAMP_LEN + UTIL_OFFSET_LEN) +// #define UTIL_TS_ISO6801_MSEC UTIL_TS_ISO6801 UTIL_TS_MSEC #define +// UTIL_TS_ISO6801_LEN (UTIL_TS_ISO6801_LEN + UTIL_TS_MSEC_LEN) +// #define UTIL_TS_ISO6801_USEC UTIL_TS_ISO6801_MSEC UTIL_TS_MSEC +// #define UTIL_TS_ISO6801_LEN (UTIL_TS_ISO6801_MSEC_LEN + +// UTIL_TS_MSEC_LEN) + +// #define UTIL_DTS_ISO6801_Z UTIL_DATESTAMP UTIL_TS_ISO6801_Z +// #define UTIL_DTS_ISO6801_Z_LEN (UTIL_DATESTAMP_LEN + +// UTIL_TS_ISO6801_Z_LEN) #define UTIL_DTS_ISO6801 UTIL_DATESTAMP +// UTIL_TS_ISO6801 #define UTIL_DTS_ISO6801_LEN (UTIL_DATESTAMP_LEN + +// UTIL_TS_ISO6801_LEN) #define UTIL_DTS_ISO6801_MSEC UTIL_DATESTAMP +// UTIL_TS_ISO6801_MSEC #define UTIL_DTS_ISO6801_LEN (UTIL_DATESTAMP_LEN + +// UTIL_TS_ISO6801_LEN) #define UTIL_DTS_ISO6801_USEC UTIL_DATESTAMP +// UTIL_TS_ISO6801_USEC #define UTIL_DTS_ISO6801_LEN (UTIL_DATESTAMP_LEN + +// UTIL_TS_ISO6801_LEN) /** * @brief Formats an ISO6801 YYYY-MM-DD datestamp at the string provided - * + * * @param dst_str pointer to string to be formatted - * + * * @param time time to be stamped - * + * * @return the length of the formatted string upon success, -1 upon failure -*/ -int8_t UTIL_time_iso8601_datestamp_UTC(char* dst_str, time_t time); + */ +int8_t UTIL_time_iso8601_datestamp_UTC(char *dst_str, time_t time); /** * @brief Formats an ISO6801 YYYY-MM-DD datestamp at the string provided - * + * * @param dst_str pointer to string to be formatted - * + * * @param time time to be stamped - * + * * @return the length of the formatted string upon success, -1 upon failure -*/ -int8_t UTIL_time_iso8601_datestamp_local(char* dst_str, time_t time); + */ +int8_t UTIL_time_iso8601_datestamp_local(char *dst_str, time_t time); /** - * @brief Formats an ISO6801 THH:MM:SSZ timestamp at the string provided (UTC/Zulu time) - * + * @brief Formats an ISO6801 THH:MM:SSZ timestamp at the string provided + * (UTC/Zulu time) + * * @param dst_str pointer to string to be formatted - * + * * @param time time to be stamped - * + * * @return the length of the formatted string upon success, -1 upon failure -*/ -int8_t UTIL_time_iso8601_timestamp_UTC(char* dst_str, time_t time); + */ +int8_t UTIL_time_iso8601_timestamp_UTC(char *dst_str, time_t time); /** - * @brief Formats an ISO6801 THH:MM:SS timestamp at the string provided (local time) - * + * @brief Formats an ISO6801 THH:MM:SS timestamp at the string provided (local + * time) + * * @param dst_str pointer to string to be formatted - * + * * @param time time to be stamped - * + * * @return the length of the formatted string upon success, -1 upon failure -*/ -int8_t UTIL_time_iso8601_timestamp_local(char* dst_str, time_t time); + */ +int8_t UTIL_time_iso8601_timestamp_local(char *dst_str, time_t time); /** * @brief Formats the millesecond portion of a timestamp at the string provided - * + * * @param dst_str pointer to string to be formatted - * + * * @param time time to be stamped - * + * * @return the length of the formatted string upon success, -1 upon failure -*/ -int8_t UTIL_time_msec_timestamp(char* dst_str, __useconds_t time); + */ +int8_t UTIL_time_msec_timestamp(char *dst_str, __useconds_t time); /** - * @brief Formats the milli- and micro- second portion of a timestamp at the string provided - * + * @brief Formats the milli- and micro- second portion of a timestamp at the + * string provided + * * @param dst_str pointer to string to be formatted - * + * * @param time time to be stamped - * + * * @return the length of the formatted string upon success, -1 upon failure -*/ -int8_t UTIL_time_msec_usec_timestamp(char* dst_str, __useconds_t time); + */ +int8_t UTIL_time_msec_usec_timestamp(char *dst_str, __useconds_t time); /** * @brief Formats a ISO6801 timezone offset (+TH:TM) at the string provided - * + * * @param dst_str pointer to string to be formatted - * - * @param tz_offset_sec timezone offset in minutes compared to UTC (a value of zero will result in a "Z", like UTC) - * + * + * @param tz_offset_sec timezone offset in minutes compared to UTC (a value of + * zero will result in a "Z", like UTC) + * * @return the length of the formatted string upon success, -1 upon failure -*/ -int8_t UTIL_time_iso8601_time_offset(char* dst_str, int16_t tz_offset_sec); + */ +int8_t UTIL_time_iso8601_time_offset(char *dst_str, int16_t tz_offset_sec); /** - * @brief Formats a complete ISO6801 date-time stamp, with offset (YYYY-MM-DDTHH:MM:SS+TH:TM) at the string provided - * + * @brief Formats a complete ISO6801 date-time stamp, with offset + * (YYYY-MM-DDTHH:MM:SS+TH:TM) at the string provided + * * @param dst_str pointer to string to be formatted - * + * * @param time time to be stamped - * - * @param tz_offset_min timezone offset in minutes compared to UTC (a value of zero will result in a "Z", like UTC) - * + * + * @param tz_offset_min timezone offset in minutes compared to UTC (a value of + * zero will result in a "Z", like UTC) + * * @return the length of the formatted string upon success, -1 upon failure -*/ -int8_t UTIL_time_iso8601_complete_datetime(char* dst_str, time_t time, int16_t tz_offset_min); + */ +int8_t UTIL_time_iso8601_complete_datetime(char *dst_str, time_t time, + int16_t tz_offset_min); #ifdef __cplusplus }