<commit_before>/*
 * Connection.cpp
 *
 *  Created on: Jul 4, 2011
 *      Author: augcampos
 */

#include "asteriskcpp/manager/ManagerConnection.h"
#include <exception>
#include <memory>
#include <boost/format.hpp>
#include <boost/regex.hpp>
#include "asteriskcpp/exceptions/Exception.h"
#include "asteriskcpp/utils/LogHandler.h"
#include "asteriskcpp/utils/StringUtils.h"
#include "asteriskcpp/utils/MD5.h"
#include "asteriskcpp/manager/actions/ChallengeAction.h"
#include "asteriskcpp/manager/actions/LoginAction.h"
#include "asteriskcpp/manager/actions/LogoffAction.h"
#include "asteriskcpp/manager/responses/ChallengeResponse.h"

#define DEFAULT_TIMEOUT  2000
#define DEFAULT_HOSTNAME "localhost"
#define DEFAULT_PORT  5038

static const char* status[] = {"Disconnected", "Connected", "Authenticated"};

namespace asteriskcpp {

    ManagerConnection::ManagerConnection() :
    state(DISCONNECTED), hostname(DEFAULT_HOSTNAME), port(DEFAULT_PORT), ssl(false), defaultResponseTimeout(DEFAULT_TIMEOUT), socket(NULL) {
    }

    ManagerConnection::~ManagerConnection() {
        disconnect();
    }

    bool ManagerConnection::connect(const std::string& server, unsigned int port) {
        this->setHostname(server);
        if (port > 0) {
            this->setPort(port);
        }
        return (this->connect());
    }

    bool ManagerConnection::connect() {
        try {
            LOG_INFO_STR((boost::format("Connecting to %1%:%2% ") % this->getHostname() % this->getPort()).str());
            IPAddress ip(this->getHostname(), this->getPort());
            this->socket = new TCPSocket(ip);
            LOG_INFO_STR("Success");
            this->setState(CONNECTED);
            return (true);
        } catch (...) {
        }
        disconnect();
        return (false);
    }

    void ManagerConnection::disconnect() {
        if (state != DISCONNECTED) {
            this->setState(DISCONNECTED);
            if (this->socket != NULL) {
                delete (socket);
                this->socket = NULL;
            }
        }
    }

    void ManagerConnection::send(const std::string& data) {
        LOG_DEBUG_STR(str2Log(data));

        if (this->state == DISCONNECTED) {
            LOG_TRACE_STR("OUT :state is DISCONNECTED");
            return;
        }

        try {
            this->socket->writeData(data);
        } catch (Exception& E) {
            LOG_ERROR_STR(E.getMessage());
            this->reader.stop();
            this->notifyDisconnect();
        }

        LOG_TRACE_STR("OUT");
    }

    void ManagerConnection::sendAction(ManagerAction* action) {
        sendAction(action, NULL);
    }

    void ManagerConnection::sendAction(ManagerAction* action, responseCallbackFunction_t rcbf) {
        ASyncResponseCallBack *asrcb = new ASyncResponseCallBack(action, defaultResponseTimeout, rcbf);
        addResponsetListener(action->generateID(), asrcb);
        send(action->toString());
    }

    ManagerResponse* ManagerConnection::syncSendAction(ManagerAction& action) {
        return (syncSendAction(action, defaultResponseTimeout));
    }

    ManagerResponse* ManagerConnection::syncSendAction(ManagerAction& action, unsigned int timeout) {
        LOG_TRACE_STR("IN");
        SyncResponseCallBack *srcb = new SyncResponseCallBack(&action, timeout);
        addResponsetListener(action.generateID(), srcb);
        send(action.toString());
        ManagerResponse* mr = srcb->stoll();
        return mr;
    }

    void ManagerConnection::addEventCallback(onManagerEventCallback_t callback) {
        ASyncEventCallBack *asecb = new ASyncEventCallBack(callback);
        addEventListener(*asecb);
    }

    ManagerConnection::State ManagerConnection::getState() const {
        return (state);
    }

    void ManagerConnection::dispatchAsteriskVersion(AsteriskVersion *version) {
        LOG_DEBUG_STR("SET ASTERISK VERSTION " + (*version).toString())
        asteriskVersion = version;
    }

    unsigned int ManagerConnection::getDefaultResponseTimeout() const {
        return (defaultResponseTimeout);
    }

    std::string ManagerConnection::getHostname() const {
        return (hostname);
    }

    std::string ManagerConnection::getPassword() const {
        return (password);
    }

    unsigned int ManagerConnection::getPort() const {
        return (port);
    }

    std::string ManagerConnection::getUsername() const {
        return (username);
    }

    bool ManagerConnection::isSsl() const {
        return (ssl);
    }

    void ManagerConnection::setDefaultResponseTimeout(unsigned int defaultResponseTimeout) {
        this->defaultResponseTimeout = defaultResponseTimeout;
    }

    void ManagerConnection::setHostname(std::string hostname) {
        this->hostname = hostname;
    }

    void ManagerConnection::setPassword(std::string password) {
        this->password = password;
    }

    void ManagerConnection::setPort(unsigned int port) {
        this->port = port;
    }

    void ManagerConnection::setSsl(bool ssl) {
        this->ssl = ssl;
    }

    void ManagerConnection::setState(State newState) {
        if (this->state == newState)
            return;

        std::stringstream transition;
        transition << status[state] << " => " << status[newState];
        LOG_DEBUG_DATA(transition.str());

        switch (state) { //from state..
            case DISCONNECTED:
                if (newState != CONNECTED) {
                    throw new Exception(transition.str());
                }
                //transition to connected
                LOG_INFO_STR("CONNECTED");
                this->reader.start(socket, this);
                ManagerResponsesHandler::start();
                break;
            case CONNECTED:
                if (newState == DISCONNECTED) {
                    //to disconnected
                    LOG_INFO_STR("DISCONNECTED");
                    ManagerResponsesHandler::stop();<commit_msg>fix problem   make plural event process thread<commit_after>/*
 * Connection.cpp
 *
 *  Created on: Jul 4, 2011
 *      Author: augcampos
 */

#include "asteriskcpp/manager/ManagerConnection.h"
#include <exception>
#include <memory>
#include <boost/format.hpp>
#include <boost/regex.hpp>
#include "asteriskcpp/exceptions/Exception.h"
#include "asteriskcpp/utils/LogHandler.h"
#include "asteriskcpp/utils/StringUtils.h"
#include "asteriskcpp/utils/MD5.h"
#include "asteriskcpp/manager/actions/ChallengeAction.h"
#include "asteriskcpp/manager/actions/LoginAction.h"
#include "asteriskcpp/manager/actions/LogoffAction.h"
#include "asteriskcpp/manager/responses/ChallengeResponse.h"

#define DEFAULT_TIMEOUT  2000
#define DEFAULT_HOSTNAME "localhost"
#define DEFAULT_PORT  5038

static const char* status[] = {"Disconnected", "Connected", "Authenticated"};

namespace asteriskcpp {

    ManagerConnection::ManagerConnection() :
    state(DISCONNECTED), hostname(DEFAULT_HOSTNAME), port(DEFAULT_PORT), ssl(false), defaultResponseTimeout(DEFAULT_TIMEOUT), socket(NULL) {
        ManagerResponsesHandler::start();
    }

    ManagerConnection::~ManagerConnection() {
        ManagerResponsesHandler::stop();
        disconnect();
    }

    bool ManagerConnection::connect(const std::string& server, unsigned int port) {
        this->setHostname(server);
        if (port > 0) {
            this->setPort(port);
        }
        return (this->connect());
    }

    bool ManagerConnection::connect() {
        try {
            LOG_INFO_STR((boost::format("Connecting to %1%:%2% ") % this->getHostname() % this->getPort()).str());
            IPAddress ip(this->getHostname(), this->getPort());
            this->socket = new TCPSocket(ip);
            LOG_INFO_STR("Success");
            this->setState(CONNECTED);
            return (true);
        } catch (...) {
        }
        disconnect();
        return (false);
    }

    void ManagerConnection::disconnect() {
        if (state != DISCONNECTED) {
            this->setState(DISCONNECTED);
            if (this->socket != NULL) {
                delete (socket);
                this->socket = NULL;
            }
        }
    }

    void ManagerConnection::send(const std::string& data) {
        LOG_DEBUG_STR(str2Log(data));

        if (this->state == DISCONNECTED) {
            LOG_TRACE_STR("OUT :state is DISCONNECTED");
            return;
        }

        try {
            this->socket->writeData(data);
        } catch (Exception& E) {
            LOG_ERROR_STR(E.getMessage());
            this->reader.stop();
            this->notifyDisconnect();
        }

        LOG_TRACE_STR("OUT");
    }

    void ManagerConnection::sendAction(ManagerAction* action) {
        sendAction(action, NULL);
    }

    void ManagerConnection::sendAction(ManagerAction* action, responseCallbackFunction_t rcbf) {
        ASyncResponseCallBack *asrcb = new ASyncResponseCallBack(action, defaultResponseTimeout, rcbf);
        addResponsetListener(action->generateID(), asrcb);
        send(action->toString());
    }

    ManagerResponse* ManagerConnection::syncSendAction(ManagerAction& action) {
        return (syncSendAction(action, defaultResponseTimeout));
    }

    ManagerResponse* ManagerConnection::syncSendAction(ManagerAction& action, unsigned int timeout) {
        LOG_TRACE_STR("IN");
        SyncResponseCallBack *srcb = new SyncResponseCallBack(&action, timeout);
        addResponsetListener(action.generateID(), srcb);
        send(action.toString());
        ManagerResponse* mr = srcb->stoll();
        return mr;
    }

    void ManagerConnection::addEventCallback(onManagerEventCallback_t callback) {
        ASyncEventCallBack *asecb = new ASyncEventCallBack(callback);
        addEventListener(*asecb);
    }

    ManagerConnection::State ManagerConnection::getState() const {
        return (state);
    }

    void ManagerConnection::dispatchAsteriskVersion(AsteriskVersion *version) {
        LOG_DEBUG_STR("SET ASTERISK VERSTION " + (*version).toString())
        asteriskVersion = version;
    }

    unsigned int ManagerConnection::getDefaultResponseTimeout() const {
        return (defaultResponseTimeout);
    }

    std::string ManagerConnection::getHostname() const {
        return (hostname);
    }

    std::string ManagerConnection::getPassword() const {
        return (password);
    }

    unsigned int ManagerConnection::getPort() const {
        return (port);
    }

    std::string ManagerConnection::getUsername() const {
        return (username);
    }

    bool ManagerConnection::isSsl() const {
        return (ssl);
    }

    void ManagerConnection::setDefaultResponseTimeout(unsigned int defaultResponseTimeout) {
        this->defaultResponseTimeout = defaultResponseTimeout;
    }

    void ManagerConnection::setHostname(std::string hostname) {
        this->hostname = hostname;
    }

    void ManagerConnection::setPassword(std::string password) {
        this->password = password;
    }

    void ManagerConnection::setPort(unsigned int port) {
        this->port = port;
    }

    void ManagerConnection::setSsl(bool ssl) {
        this->ssl = ssl;
    }

    void ManagerConnection::setState(State newState) {
        if (this->state == newState)
            return;

        std::stringstream transition;
        transition << status[state] << " => " << status[newState];
        LOG_DEBUG_DATA(transition.str());

        switch (state) { //from state..
            case DISCONNECTED:
                if (newState != CONNECTED) {
                    throw new Exception(transition.str());
                }
                //transition to connected
                LOG_INFO_STR("CONNECTED");
                this->reader.start(socket, this);
                break;
            case CONNECTED:
                if (newState == DISCONNECTED) {
                    //to disconnected
                    LOG_INFO_STR("DISCONNECTED");
{'fraction_non_alphanumeric': 0.11847743887068314, 'fraction_numerical': 0.003024955886059995, 'mean_word_length': 2.6951257373486497, 'pattern_counts': {'":': 0, '<': 23, '<?xml version=': 0, '>': 69, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7141734', 'n_tokens_mistral': 3272, 'n_tokens_neox': 3185, 'n_words': 607}