void CalaosConnection::onDisconnected()
{
    if (con_state == CALAOS_CON_LOGIN)
    {
        error_login.emit();

        cCriticalDom("network.connection") << "Login failed !";

        return;
    }

    lost_connection.emit();

    cCriticalDom("network.connection") << "Connection closed !";
}
void CalaosConnection::timeoutSend(CalaosCmd *cmd)
{
    if (con_state == CALAOS_CON_OK)
    {
        cCriticalDom("network.connection") << "Timeout waiting for answer... give up.";

        cmd->callback(nullptr, cmd->user_data);
        commands.erase(cmd->msgid);
        delete cmd;
    }
}
void CalaosConnection::timeoutConnect()
{
    if (con_state == CALAOS_CON_NONE)
    {
        timeout_connect.emit();

        cCriticalDom("network.connection") << "Timeout connecting to " << host;
    }

    DELETE_NULL(timeout);
}
static Eina_Bool _con_server_add(void *data, int type, Ecore_Con_Event_Server_Add *ev)
{
    AVReceiver *o = reinterpret_cast<AVReceiver *>(data);

    if (ev && ev->server && (o != ecore_con_server_data_get(ev->server)))
        return ECORE_CALLBACK_PASS_ON;

    if (o)
        o->addConnection(ev->server);
    else
        cCriticalDom("output") << "failed to get object !";
    return ECORE_CALLBACK_RENEW;
}
void HttpServer::dataWritten(Ecore_Con_Client *client, int size)
{
    cDebugDom("network")
            << Utils::to_string(size) << " bytes written"
            << " to client at address "
            << ecore_con_client_ip_get(client);

    std::map<Ecore_Con_Client *, WebSocket *>::iterator it = connections.find(client);
    if (it == connections.end())
    {
        cCriticalDom("network") << "Can't find corresponding HttpClient !";

        return;
    }

    it->second->DataWritten(size);
}
void HttpServer::delConnection(Ecore_Con_Client *client)
{
    cDebugDom("network")
            << "Connection from adress "
            << ecore_con_client_ip_get(client) << " closed.";

    std::map<Ecore_Con_Client *, WebSocket *>::iterator it = connections.find(client);
    if (it == connections.end())
    {
        cCriticalDom("network") << "Can't find corresponding HttpClient !";

        return;
    }

    delete it->second;
    connections.erase(it);
}
void HttpServer::getDataConnection(Ecore_Con_Client *client, void *data, int size)
{
    std::string d((char *)data, size);

    cDebugDom("network")
            << "Got data from client at address "
            << ecore_con_client_ip_get(client);

    std::map<Ecore_Con_Client *, WebSocket *>::iterator it = connections.find(client);
    if (it == connections.end())
    {
        cCriticalDom("network") << "Can't find corresponding HttpClient !";

        return;
    }

    it->second->ProcessData(d);
}
Eina_Bool _ecore_con_handler_client_del(void *data, int type, Ecore_Con_Event_Client_Del *ev)
{
    HttpServer *tcpserver = reinterpret_cast<HttpServer *>(data);

    if (ev && (tcpserver != ecore_con_server_data_get(ecore_con_client_server_get(ev->client))))
    {
        return ECORE_CALLBACK_PASS_ON;
    }

    if (tcpserver)
    {
        tcpserver->delConnection(ev->client);
    }
    else
    {
        cCriticalDom("network") << "failed to get HttpServer object !";
    }

    return ECORE_CALLBACK_CANCEL;
}
Eina_Bool _ecore_con_handler_data_write(void *data, int type, Ecore_Con_Event_Client_Write *ev)
{
    HttpServer *tcpserver = reinterpret_cast<HttpServer *>(data);

    if (ev && (tcpserver != ecore_con_server_data_get(ecore_con_client_server_get(ev->client))))
    {
        return ECORE_CALLBACK_PASS_ON;
    }

    if (tcpserver)
    {
        tcpserver->dataWritten(ev->client, ev->size);
    }
    else
    {
        cCriticalDom("network") << "failed to get HttpServer object !";
    }

    return ECORE_CALLBACK_RENEW;
}
void FileDownloader::completeCb(int status)
{
    ecore_con_url_free(url_con);
    url_con = NULL;

    fclose(dl_file);

    if (status >= 400 || status < 100)
    {
        std::string err = "Error code : " + Utils::to_string(status);

        IPC::Instance().SendEvent("downloader::" + Utils::to_string(this),
                                  "failed",
                                  IPCData(new std::string(err), new Utils::DeletorT<std::string *>()),
                                  true);

        cb_signal.emit("failed", &err);
        cb_signal_user.emit("failed", &err, user_data);

        cErrorDom("downloader") << "Download failed: " << err;

        if (dest.empty())
            ecore_file_unlink(tmpFile.c_str());

        return;
    }

    cDebugDom("downloader") << "Download done. (" << url << ")";

    if (!dest.empty())
    {
        IPC::Instance().SendEvent("downloader::" + Utils::to_string(this),
                                  "done",
                                  IPCData(new std::string(dest), new Utils::DeletorT<std::string *>()),
                                  true);

        cb_signal.emit("done", &dest);
        cb_signal_user.emit("done", &dest, user_data);
    }
    else
    {
        Utils::Buffer_CURL buff;

        dl_file = fopen(tmpFile.c_str(), "rb");
        fseek(dl_file, 0, SEEK_END);
        buff.bufsize = ftell(dl_file);
        fseek(dl_file, 0, SEEK_SET);
        buff.buffer = (char *)malloc(buff.bufsize);
        if (fread(buff.buffer, buff.bufsize, 1, dl_file) <= 0)
            cCriticalDom("downloader") << "FileDownloader: fread failed ! (" << url << ")";
        fclose(dl_file);

        ecore_file_unlink(tmpFile.c_str());

        IPC::Instance().SendEvent("downloader::" + Utils::to_string(this),
                                  "done",
                                  IPCData(new Utils::Buffer_CURL(buff), new Utils::DeletorT<Utils::Buffer_CURL *>()),
                                  true);

        cb_signal.emit("done", &buff);
        cb_signal_user.emit("done", &buff, user_data);

        if (buff.buffer)
            free(buff.buffer);
    }

    if (auto_destroy)
    {
        Destroy();
    }
}