コード例 #1
0
void CalaosCameraView::play()
{
    if (ecurl)
        ecore_con_url_free(ecurl);

    ecurl = ecore_con_url_new(cameraUrl.c_str());
    if (!ecurl)
    {
        cErrorDom("camera") << "Failed to create ecore_con_url!";
        return;
    }
    ecore_con_url_data_set(ecurl, this);
    ecore_con_url_ssl_verify_peer_set(ecurl, false);

    single_frame = false;
    buffer.clear();
    formatDetected = false;
    format_error = false;
    nextContentLength = -1;

    if (!ecore_con_url_get(ecurl))
    {
        cErrorDom("camera") << "Could not realize request!";
        ecore_con_url_free(ecurl);
        ecurl = nullptr;
    }

    cDebugDom("camera") << "Request started to " << cameraUrl;
}
コード例 #2
0
ファイル: JsonApiV3.cpp プロジェクト: DjMomo/calaos_base
void JsonApiV3::sendJson(const string &msg_type, json_t *data, const string &client_id)
{
    json_t *jroot = json_object();
    json_object_set_new(jroot, "msg", json_string(msg_type.c_str()));
    if (client_id != "")
        json_object_set_new(jroot, "msg_id", json_string(client_id.c_str()));
    if (data)
        json_object_set(jroot, "data", data);

    char *d = json_dumps(jroot, JSON_COMPACT | JSON_ENSURE_ASCII /*| JSON_ESCAPE_SLASH*/);
    if (!d)
    {
        cErrorDom("network") << "json_dumps failed! msg_type: " << msg_type << " data:" << data;
        json_decref(jroot);

        //close connection
        closeConnection.emit(WebSocket::CloseCodeNormal, "json_dumps failed!");

        return;
    }

    json_decref(jroot);
    string res(d);
    free(d);

    sendData.emit(res);
}
コード例 #3
0
ファイル: xPLController.cpp プロジェクト: calaos/calaos_base
void xPLController::Connect()
{
    int portTCP;


    m_UdpRecvHandle = uvw::Loop::getDefault()->resource<uvw::UDPHandle>();

    m_UdpRecvHandle->on<uvw::UDPDataEvent>([this](const uvw::UDPDataEvent &ev, auto &)
    {
        this->udpListenData(ev.data.get(), ev.length, ev.sender.ip, ev.sender.port);
    });

    m_UdpRecvHandle->once<uvw::ErrorEvent>([this](const uvw::ErrorEvent &ev, uvw::UDPHandle &h)
    {
        cErrorDom("xpl") << "xPL UDP server error : " << ev.what();
        h.once<uvw::CloseEvent>([this](auto &, auto &)
        {
            Timer::singleShot(2.5, (sigc::slot<void>)sigc::mem_fun(*this, &xPLController::Connect));
        });
        h.close();
    });

    portTCP = discoverxPLPort();
    m_UdpRecvHandle->broadcast(true);
    cInfoDom("xpl") << "Listening on port " << portTCP;
    m_UdpRecvHandle->bind("0.0.0.0", portTCP, uvw::UDPHandle::Bind::REUSEADDR);
    m_UdpRecvHandle->recv();
    m_xPLDevice.SetRecvSockInfo(localAddress(), portTCP);
    m_xPLDevice.Close();
    m_xPLDevice.Open();
}
コード例 #4
0
bool Condition::Evaluate()
{

    cErrorDom("rule.condition") <<  "Can't evaluate base Condition class !";

    return false;
}
コード例 #5
0
void _item_sel_cb(void *data, Evas_Object *obj, void *event_info)
{
    GenlistItemBase *item = reinterpret_cast<GenlistItemBase *>(data);
    if (!item)
    {
        cErrorDom("home") << "GenlistItemBase : _item_sel_cb(): Can't cast data !";
        return;
    }
    item->emitSelectedSignal();
}
コード例 #6
0
Evas_Object *_item_part_get(void *data, Evas_Object *obj, const char *part)
{
    GenlistItemBase *item = reinterpret_cast<GenlistItemBase *>(data);
    if (!item)
    {
        cErrorDom("home") << "GenlistItemBase : _item_part_get(): Can't cast data !";
        return NULL;
    }

    return item->getPartItem(obj, part);
}
コード例 #7
0
void _item_delete(void *data, Evas_Object *obj)
{
    GenlistItemBase *item = reinterpret_cast<GenlistItemBase *>(data);
    if (!item)
    {
        cErrorDom("home") << "GenlistItemBase : _item_delete(): Can't cast data !";
        return;
    }

    delete item;
}
コード例 #8
0
Eina_Bool _item_state(void *data, Evas_Object *obj, const char *part)
{
    GenlistItemBase *item = reinterpret_cast<GenlistItemBase *>(data);
    if (!item)
    {
        cErrorDom("home") << "GenlistItemBase : _item_state(): Can't cast data !";
        return false;
    }

    return item->getStateItem(obj, part);
}
コード例 #9
0
char *_item_label(void *data, Evas_Object *obj, const char *part)
{
    GenlistItemBase *item = reinterpret_cast<GenlistItemBase *>(data);
    if (!item)
    {
        cErrorDom("home") << "GenlistItemBase : _item_label(): Can't cast data !";
        return NULL;
    }

    return strdup(item->getLabelItem(obj, part).c_str());
}
コード例 #10
0
ファイル: xPLController.cpp プロジェクト: calaos/calaos_base
void xPLSockWrapper::Connect()
{
    m_UdpSenderHandle = uvw::Loop::getDefault()->resource<uvw::UDPHandle>();
    m_UdpSenderHandle->bind("255.255.255.255", XPL_DEFAULT_PORT, uvw::UDPHandle::Bind::REUSEADDR);
    m_UdpSenderHandle->broadcast(true);

    m_UdpSenderHandle->once<uvw::ErrorEvent>([this](const uvw::ErrorEvent &ev, uvw::UDPHandle &h)
    {
        cErrorDom("xpl") << "xPL UDP client error : " << ev.what();
        h.once<uvw::CloseEvent>([this](auto &, auto &)
        {
            Timer::singleShot(2.5, (sigc::slot<void>)sigc::mem_fun(*this, &xPLSockWrapper::Connect));
        });
        h.close();
    });
}
コード例 #11
0
void CalaosCameraView::requestCompleted()
{
    if (single_frame)
    {
        evas_object_image_memfile_set(camImage, &buffer[0], buffer.size(), NULL, NULL);

        Evas_Load_Error err = evas_object_image_load_error_get(camImage);
        if (err != EVAS_LOAD_ERROR_NONE)
            cErrorDom("camera") << "could not load image. error string is \"%s\"" << evas_load_error_str(err);
    }

    if (format_error)
        return;

    EcoreTimer::singleShot(0, [=]()
    {
        if (!single_frame)
            cWarningDom("camera") << "Restarting request to camera...";
        play();
    });
}
コード例 #12
0
ファイル: xPLController.cpp プロジェクト: calaos/calaos_base
void xPLController::udpListenData(const char *data, std::size_t length, string remoteIp, int remotePort)
{
    string xPLRaw(data, length);
    xPL::SchemaObject xPLparse;
    string key;
    xPLInfoSensor infoSensor;
    std::unordered_map<string, sigc::signal<void, xPLInfoSensor*>>::iterator it;


    while(xPLRaw!="")
    {
        try
        {
            xPLRaw = xPLparse.Parse(xPLRaw);
        }
        catch(const xPL::SchemaObject::Exception &e)
        {
            cErrorDom("xpl") <<  "Failed to parse : " << e.what();
            return;
        }

        if(m_xPLDevice.MsgForMe(xPLparse) && m_xPLDevice.MsgAnswer(xPLparse)) continue;

        xPL::ISchema::MsgType msgType = xPLparse.GetMsgType();
        if((msgType!=xPL::ISchema::MsgType::stat)&&(msgType!=xPL::ISchema::MsgType::trig)) continue;
        if(xPLparse.GetClass()!="sensor") continue;
        if(xPLparse.GetType()!="basic") continue;

        key = xPLparse.GetSource()+":"+xPLparse.GetValue("device");

        it = m_sensorsChangeCb.find(key);
        if(it != m_sensorsChangeCb.end())
        {
            infoSensor.StringVal = xPLparse.GetValue("current");
            infoSensor.AnalogVal = xPLparse.GetValue<float>("current");
            (it->second).emit(&infoSensor);
        }
    }
}
コード例 #13
0
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();
    }
}
コード例 #14
0
bool FileDownloader::Start()
{
    cDebugDom("downloader") << "Start download (" << url << ")";

    if (url_con)
    {
        cWarningDom("downloader") << "A download is already in progress...";

        return false;
    }

    url_con = ecore_con_url_new(url.c_str());
    if (!url_con)
    {
        std::string err = "Failed to create Ecore_Con_Url";

        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;

        return false;
    }

    if (dest.empty())
    {
        //Create a temporary file for download
        int cpt = 0;

        //Get a temporary filename
        do
        {
            tmpFile = "/tmp/calaos" + Utils::to_string(getpid()) + "_download_tmp_";
            tmpFile += Utils::to_string(cpt);
            cpt++;
        }
        while (ecore_file_exists(tmpFile.c_str()));

        dl_file = fopen(tmpFile.c_str(), "wb");
    }
    else
    {
        dl_file = fopen(dest.c_str(), "wb");
    }

    if (!dl_file)
    {
        std::string err = "Failed to open file";

        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;

        ecore_con_url_free(url_con);
        url_con = NULL;

        return false;
    }

    ecore_con_url_fd_set(url_con, fileno(dl_file));
    ecore_con_url_data_set(url_con, this);
    ecore_con_url_ssl_verify_peer_set(url_con, false);

    bool ret = false;
    if (postData.empty())
    {
        ret = ecore_con_url_get(url_con);
    }
    else
    {
        ret = ecore_con_url_post(url_con, postData.c_str(), postData.length(), postContentType.c_str());
    }

    if (!ret)
    {
        std::string err = "Failed to call GET/POST";

        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;

        ecore_con_url_free(url_con);
        url_con = NULL;
        fclose(dl_file);

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

        return false;
    }

    return true;
}
コード例 #15
0
void CalaosConnection::onMessageReceived(const string &data)
{
    Params jsonRoot;
    Params jsonData;

    //parse the json data
    json_error_t jerr;
    json_t *jroot = json_loads(data.c_str(), 0, &jerr);

    if (!jroot || !json_is_object(jroot))
    {
        cDebugDom("network") << "Error loading json : " << jerr.text;
        return;
    }

    char *d = json_dumps(jroot, JSON_INDENT(4));
    if (d)
    {
        cDebugDom("network") << d;
        free(d);
    }

    //decode the json root object into jsonParam
    jansson_decode_object(jroot, jsonRoot);

    json_t *jdata = json_object_get(jroot, "data");
    if (jdata)
        jansson_decode_object(jdata, jsonData);

    //Format: { msg: "type", msg_id: id, data: {} }

    if (jsonRoot["msg"] == "login" &&
        jsonData["success"] == "true" &&
        con_state == CALAOS_CON_LOGIN)
    {
        DELETE_NULL(timeout);
        con_state = CALAOS_CON_OK;

        cDebugDom("network.connection") << "Successfully logged in.";

        connection_ok.emit();
        return;
    }

    //a message id was sent, get the corresponding
    //query and call the callback
    if (!jsonRoot["msg_id"].empty())
    {
        if (commands.find(jsonRoot["msg_id"]) == commands.end())
        {
            cErrorDom("network") << "msg_id " << jsonRoot["msg_id"] << " not found in commands.";
        }
        else
        {
            CalaosCmd *cmd = commands[jsonRoot["msg_id"]];
            cmd->callback(jdata, cmd->user_data);
            commands.erase(jsonRoot["msg_id"]);
            delete cmd;
        }
    }

    if (jsonRoot["msg"] == "event")
    {
        Params eventData;
        jansson_decode_object(json_object_get(jdata, "data"), eventData);
        string ev = jsonData["type_str"];

        if (ev == "input_added" ||
            ev == "output_added")
            notify_io_new.emit(ev, eventData);

        else if (ev == "input_deleted" ||
                 ev == "output_deleted")
            notify_io_delete.emit(ev, eventData);

        else if (ev == "input_changed" ||
                 ev == "output_changed" ||
                 ev == "input_prop_deleted" ||
                 ev == "output_prop_deleted" ||
                 ev == "timerange_changed")
            notify_io_change.emit(ev, eventData);

        else if (ev == "room_added")
            notify_room_new.emit(ev, eventData);

        else if (ev == "room_deleted")
            notify_room_delete.emit(ev, eventData);

        else if (ev == "room_changed" ||
                 ev == "room_prop_deleted")
            notify_room_change.emit(ev, eventData);

        else if (ev == "scenario_deleted")
            notify_scenario_del.emit(ev, eventData);

        else if (ev == "scenario_added")
            notify_scenario_add.emit(ev, eventData);

        else if (ev == "scenario_changed")
            notify_scenario_change.emit(ev, eventData);

        else if (ev == "audio_song_changed" ||
                 ev == "playlist_tracks_added" ||
                 ev == "playlist_tracks_deleted" ||
                 ev == "playlist_tracks_moved" ||
                 ev == "playlist_reload" ||
                 ev == "playlist_cleared" ||
                 ev == "audio_status_changed" ||
                 ev == "audio_volume_changed")
            notify_audio_change.emit(ev, eventData);
    }
}
コード例 #16
0
HueOutputLightRGB::HueOutputLightRGB(Params &p):
    OutputLightRGB(p)
{
    ioDoc->friendlyNameSet("HueOutputLightRGB");
    ioDoc->descriptionSet(_("RGB Light dimmer using a Philips Hue"));
    ioDoc->linkAdd("Meet Hue", _("http://www.meethue.com"));
    ioDoc->paramAdd("host", _("Hue bridge IP address"), IODoc::TYPE_STRING, true);
    ioDoc->paramAdd("api", _("API key return by Hue bridge when assciation has been made. Use Hue Wizard in calaos_installer to get this value automatically."), IODoc::TYPE_STRING, true);
    ioDoc->paramAdd("id_hue", _("Unique ID describing the Hue Light. This value is returned by the Hue Wizard."), IODoc::TYPE_STRING, true);

    m_host = get_param("host");
    m_api = get_param("api");
    m_idHue = get_param("id_hue");

    m_timer = new EcoreTimer(2.0,[=](){
        std::string url = "http://" + m_host + "/api/" + m_api + "/lights/" + m_idHue;
        UrlDownloader *dl = new UrlDownloader(url, true);
        dl->m_signalCompleteData.connect([&](Eina_Binbuf *downloadedData, int status)
    {
         if (status)
         {
              json_error_t error;
              const unsigned char* c = eina_binbuf_string_get(downloadedData);
              json_t *root = json_loads((const char*)eina_binbuf_string_get(downloadedData), 0, &error);
              if (!root)
              {
                   cErrorDom("hue") << "Json received malformed : " << error.source
                                    << " " << error.text << " (" << Utils::to_string(error.line) << " )";
                   return;
              }
              if (!json_is_object(root))
              {
                   cErrorDom("hue") << "Protocol changed ? date received : " << eina_binbuf_string_get(downloadedData);
                   return;
              }

              json_t *tstate = json_object_get(root, "state");
              if (!tstate || !json_is_object(tstate))
              {
                   cErrorDom("hue") << "Protocol changed ? date received : " << eina_binbuf_string_get(downloadedData);
                   return;
              }

              int sat, bri, hue;
              bool on, reachable;

              sat = json_integer_value(json_object_get(tstate, "sat"));
              bri = json_integer_value(json_object_get(tstate, "bri"));
              hue = json_integer_value(json_object_get(tstate, "hue"));
              on = jansson_bool_get(tstate, "on");
              reachable = jansson_bool_get(tstate, "reachable");

              cDebugDom("hue") << "State: " << on << " Hue : " << hue << " Bri: " << bri << " Hue : " << hue << "Data : " << c;

              if (reachable)
                   stateUpdated(ColorValue::fromHsl((int)(hue * 360.0 / 65535.0),
                                                    (int)(sat * 100.0 / 255.0),
                                                    (int)(bri * 100.0 / 255.0)), on);
              else
                   stateUpdated(ColorValue(0,0,0), reachable);

              json_decref(root);
         }
         else
         {
              stateUpdated(ColorValue(0,0,0), false);
         }
    });

        if (!dl->httpGet())
             delete dl;
         });
}
コード例 #17
0
void JsonApiHandlerHttp::processConfig(json_t *jroot)
{
    json_t *jret = json_object();

    if (jsonParam["type"] == "get")
    {
        Config::Instance().SaveConfigIO();
        Config::Instance().SaveConfigRule();

        json_t *jfiles = json_object();
        json_object_set_new(jfiles, "io.xml",
                            json_string(Utils::getFileContent(Utils::getConfigFile(IO_CONFIG).c_str()).c_str()));
        json_object_set_new(jfiles, "rules.xml",
                            json_string(Utils::getFileContent(Utils::getConfigFile(RULES_CONFIG).c_str()).c_str()));
        json_object_set_new(jfiles, "local_config.xml",
                            json_string(Utils::getFileContent(Utils::getConfigFile(LOCAL_CONFIG).c_str()).c_str()));

        json_object_set_new(jret, "config_files", jfiles);
        json_object_set_new(jret, "success", json_string("true"));
    }
    else if (jsonParam["type"] == "put")
    {
        bool ret = true;
        json_t *jfiles = json_object_get(jroot, "config_files");
        if (jfiles && json_is_object(jfiles))
        {
            const char *key;
            json_t *value;

            json_object_foreach(jfiles, key, value)
            {
                if (key && json_is_string(value))
                {
                    string skey = key;
                    if (skey != IO_CONFIG &&
                            skey != RULES_CONFIG &&
                            skey != LOCAL_CONFIG)
                    {
                        cErrorDom("network") << "Error, file " << skey << " is not a valid config filename";
                        ret = false;
                        continue;
                    }

                    string filecontent = json_string_value(value);

                    ofstream ofs(Utils::getConfigFile(key), ios::out | ios::trunc);

                    if (ofs.is_open())
                    {
                        ofs << filecontent;
                        ofs.close();
                    }
                    else
                    {
                        cErrorDom("network") << "Error, key " << key << " is not a string";
                        ret = false;
                    }
                }
                else
                {
                    cErrorDom("network") << "Error, key " << key << " is not a string";
                    ret = false;
                }
            }
        }
        else
        {
コード例 #18
0
bool ActionStd::Execute()
{
    std::string tmp;
    bool ret = true;
    std::string sval;
    bool bval = false;
    double dval = 0;

    for (uint i = 0;i < outputs.size();i++)
    {
        bool ovar = false;
        switch (outputs[i]->get_type())
        {
        case TBOOL:
        {
            if (params_var[outputs[i]->get_param("id")] != "")
            {
                std::string var_id = params_var[outputs[i]->get_param("id")];
                IOBase *out = ListeRoom::Instance().get_io(var_id);
                if (out && out->get_type() == TBOOL)
                {
                    bval = out->get_value_bool();
                    ovar = true;
                }
            }

            if (ovar)
            {
                if (!outputs[i]->set_value(bval)) ret = false;
            }
            else if (params[outputs[i]->get_param("id")] == "true")
            {
                if (!outputs[i]->set_value(true)) ret = false;
            }
            else if (params[outputs[i]->get_param("id")] == "false")
            {
                if (!outputs[i]->set_value(false)) ret = false;
            }
            else
            {
                if (!outputs[i]->set_value(params[outputs[i]->get_param("id")])) ret = false;
            }
            break;
        }
        case TINT:
        {
            if (params_var[outputs[i]->get_param("id")] != "")
            {
                std::string var_id = params_var[outputs[i]->get_param("id")];
                IOBase *out = ListeRoom::Instance().get_io(var_id);
                if (out && out->get_type() == TINT)
                {
                    dval = out->get_value_double();
                    ovar = true;
                }
            }
            tmp = params[outputs[i]->get_param("id")];

            if (ovar)
            {
                if (!outputs[i]->set_value(dval)) ret = false;
            }
            else if (is_of_type<double>(tmp))
            {
                if (!outputs[i]->set_value(atof(tmp.c_str()))) ret = false;
            }
            else
            {
                if (!outputs[i]->set_value(tmp)) ret = false;
            }
            break;
        }
        case TSTRING:
        {
            if (params_var[outputs[i]->get_param("id")] != "")
            {
                std::string var_id = params_var[outputs[i]->get_param("id")];
                IOBase *out = ListeRoom::Instance().get_io(var_id);
                if (out && out->get_type() == TSTRING)
                {
                    sval = out->get_command_string();
                    ovar = true;
                }
            }
            tmp = params[outputs[i]->get_param("id")];

            if (ovar)
            {
                if (!outputs[i]->set_value(sval)) ret = false;
            }
            else if (tmp != "")
            {
                if (!outputs[i]->set_value(tmp)) ret = false;
            }

            break;
        }
        default: break;
        }
    }

    if (ret)
        cDebugDom("rule.action.standard") <<  "Ok";
    else
        cErrorDom("rule.action.standard") <<  "Failed !";

    return ret;
}
コード例 #19
0
void ModuleManager::SearchModules()
{
    for (uint i = 0; i < search_paths.size(); i++)
    {
        cInfoDom("module") << "ModuleManager: searching modules in: " << search_paths[i];
        char *fname = NULL;
        void *data = NULL;
        Eina_List *subdir = ecore_file_ls(search_paths[i].c_str());
        Eina_List *l = NULL;

        EINA_LIST_FOREACH(subdir, l, data)
        {
            fname = (char *)data;
            string p;

            p = search_paths[i];

            if (fname)
            {
                p += "/";
                p += fname;
            }
            if (p[p.length() - 1] != '/') p += "/";

            if (!ecore_file_is_dir(p.c_str()))
                continue;

            p += "module.so";

            if (!ecore_file_exists(p.c_str()))
                continue;

            bool alreadyin = false;
            for (uint im = 0; im < modules.size() && !alreadyin; im++)
            {
                ModuleDef mdef = modules[im];
                if (p == mdef.mod_fname)
                    alreadyin = true;
            }

            if (alreadyin) continue;

            //try to load the module
            void *handle = dlopen(p.c_str(), RTLD_LAZY);

            if (handle)
            {
                //object can be loaded, check version and
                CalaosModuleApi *api = (CalaosModuleApi *)dlsym(handle, "calaos_modapi");
                if (!api)
                {
                    dlclose(handle);
                    cErrorDom("module") << "ModuleManager: module " << p << ". calaos_modapi export not found: " << dlerror();
                    continue;
                }

                if (api->api_version != CALAOS_MODULE_API_VERSION)
                {
                    dlclose(handle);

                    cErrorDom("module") << "ModuleManager: module " << p << ". The API version doesn't match";

                    continue;
                }

                string module_name;
                vector<string> tok;
                Utils::split(p, tok, "/");
                if (tok.size() > 2)
                    module_name = tok[tok.size() - 2];

                string themepath = Prefix::Instance().dataDirectoryGet();
                themepath += "/widgets/" + module_name;

                ModuleDef mdef;
                mdef.mod_name = gettext(api->name);
                mdef.mod_desc = gettext(api->desc);
                mdef.mod_version = api->version;
                mdef.mod_author = api->author;
                mdef.mod_icon = themepath + "/icon.edj";
                mdef.mod_fname = p;
                mdef.handle = handle;
                mdef.inst = NULL;
                mdef.api = api;

                cInfoDom("module") << "ModuleManager: found module: " << mdef.mod_name;

                modules.push_back(mdef);
            }
            else
            {
                cWarningDom("module") << "ModuleManager: file " << p << " : failed to dlopen: " << dlerror();
            }

        }

        EINA_LIST_FREE(subdir, data)
        free(data);
    }