1 // Copyright (c) 2012 Dennco Project
3 // This program is free software: you can redistribute it and/or modify
4 // it under the terms of the GNU General Public License as published by
5 // the Free Software Foundation, either version 3 of the License, or
6 // (at your option) any later version.
8 // This program is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 // GNU General Public License for more details.
13 // You should have received a copy of the GNU General Public License
14 // along with this program. If not, see <http://www.gnu.org/licenses/>.
17 // Created by tkawata on 1/28/2012.
22 #include "TKContainer.h"
24 #include "DNTimeKeeper.h"
25 #include "DNServerHTTP.h"
26 #include "DNServerSerialPort.h"
27 #include "TKContainer.h"
28 #include "DNContainerBuilder.h"
32 #include "DNXMLElement.h"
41 DNEngine::DNEngine(const char *contentPath) :
42 mContainer(NULL),mPortNumber(9080),mHTTPServer(NULL),mSerialServer(NULL),mValid(false), mDoTickThread(NULL)
44 mTimeKeeper = new DNTimeKeeper();
45 mContainer = TKContainer::createContainer();
46 mUIPath = "/ui/index.html";
48 dnGlobal()->updateRunningStatus(DNGlobal::STOPPED);
50 std::string basePath(contentPath);
51 std::string containerRoot = basePath;
52 containerRoot.append("/Container");
54 bool succeeded = false;
55 succeeded = parseSettingFile(contentPath);
56 if (!succeeded || !dnGlobal()->isErrorStatusNormal())
58 if (dnGlobal()->updateErrorStatus(DNGlobal::ERROR))
60 dnGlobal()->setMessage1("property.xml parse error");
61 dnGlobal()->setMessage2("failed to parse setting file /property.xml");
65 dnGlobal()->setMessage1("property.xml parse error");
70 std::string dataStorePath = containerRoot;
71 dataStorePath.append("/data.db");
73 succeeded = mContainer->setDataStore(dataStorePath.c_str());
76 if (dnGlobal()->updateErrorStatus(DNGlobal::ERROR))
78 dnGlobal()->setMessage1("Initialization failed");
79 dnGlobal()->setMessage2("Failed to the setup data store");
83 dnGlobal()->setMessage1("Initialization failed");
88 succeeded = parseContainerFile(containerRoot.c_str());
91 if (dnGlobal()->updateErrorStatus(DNGlobal::ERROR))
93 dnGlobal()->setMessage1("Initialization failed");
94 dnGlobal()->setMessage2("Failed to parse container file");
98 dnGlobal()->setMessage1("Initialization failed");
106 DNEngine::~DNEngine()
130 bool DNEngine::parseSettingFile(const char *contentRoot)
134 DNXML *xml = DNXML::createXMLFromFile(contentRoot, "property.xml");
138 DNXMLElement *element = xml->getRoot();
142 std::string message = "Failed to load property.xml file";
143 TKLog::printf("ERROR wile loading property.xml file.\n%s\n",message.c_str());
144 if (dnGlobal()->updateErrorStatus(DNGlobal::ERROR))
146 dnGlobal()->setMessage1("Initialization failed");
147 dnGlobal()->setMessage2(message);
151 dnGlobal()->setMessage1("Initialization failed");
155 if (valid && element->name != "dennco")
158 std::string message = "First element of property.xml should be <dennco>";
159 TKLog::printf("ERROR wile parsing property.xml file.\n%s\n",message.c_str());
160 if (dnGlobal()->updateErrorStatus(DNGlobal::ERROR))
162 dnGlobal()->setMessage1("Initialization failed");
163 dnGlobal()->setMessage2(message);
167 dnGlobal()->setMessage1("Initialization failed");
173 DNXMLElement *e = element->inner;
176 if (e->name == "TickIntervalSec")
178 std::istringstream is(e->text);
183 setTickIntervalSec(t);
188 std::string message = "Error in property.xml. TickIntervalSec is not configured properly.";
189 TKLog::printf("ERROR wile parsing property.xml file.\n%s\n",message.c_str());
190 if (dnGlobal()->updateErrorStatus(DNGlobal::ERROR))
192 dnGlobal()->setMessage1("Initialization failed");
193 dnGlobal()->setMessage2(message);
197 dnGlobal()->setMessage1("Initialization failed");
201 else if (e->name == "UIPath")
205 else if (e->name == "EnableHTTPServer")
209 else if (e->name == "EnableSerialServer")
222 bool DNEngine::parseContainerFile(const char *containerRoot)
224 DNContainerBuilder builder(mContainer);
225 return builder.buildContainerFromXHTML(containerRoot);
229 bool DNEngine::startHTTPServer(int portNumber)
231 if (mHTTPServer && mHTTPServer->isRunning())
237 mHTTPServer = new DNServerHTTP(this);
240 mHTTPServer->setPortNumber(portNumber);
241 mHTTPServer->start();
246 void DNEngine::stopHTTPServer()
248 if (mHTTPServer && mHTTPServer->isRunning())
256 bool DNEngine::startSerialServer()
258 if (mSerialServer && mSerialServer->isRunning())
260 mSerialServer->stop();
261 delete mSerialServer;
262 mSerialServer = NULL;
264 mSerialServer = new DNServerSerialPort(this);
267 if (mSerialServer->setup())
269 mSerialServer->start();
280 void DNEngine::stopSerialServer()
282 if (mSerialServer && mSerialServer->isRunning())
284 mSerialServer->stop();
285 delete mSerialServer;
286 mSerialServer = NULL;
290 void DNEngine::setTickIntervalSec(float interval)
293 mTimeKeeper->setIntevalSec(interval);
296 bool DNEngine::startEngine()
299 mDoTickThread = DNThread::createThread(DNEngine::doTickThread, this);
301 return mDoTickThread->start();
304 bool DNEngine::stopEngine()
307 dnGlobal()->updateRunningStatus(DNGlobal::STOPPING);
310 r = mDoTickThread->waitForExit(5000);
311 delete mDoTickThread;
312 mDoTickThread = NULL;
316 mContainer->doDestroy();
317 mContainer->releaseDataStore();
323 void DNEngine::doTickThread(void *self)
325 if (!dnGlobal()->updateRunningStatus(DNGlobal::RUNNIING))
330 DNEngine *engine = (DNEngine*)self;
332 while(dnGlobal()->getRunningStatus() == DNGlobal::RUNNIING && engine->isValid())
334 engine->mContainer->doTick(engine->mTimeKeeper->getTickTime());
335 engine->mTimeKeeper->sleepUntilNextInterval();
338 dnGlobal()->updateRunningStatus(DNGlobal::STOPPED);
341 float DNEngine::doClientGetRequest(const char* path)
343 std::string fqn = getFQNString("/",path);
344 TKUICell *cell = (TKUICell*)mContainer->getInterfaceCell(fqn);
348 result = cell->getValue();
353 bool DNEngine::doClientSetRequest(const char* path, const char* value)
355 return doClientSetRequest(path, atof(value));
358 bool DNEngine::doClientSetRequest(const char* path, float value)
360 std::string fqn = getFQNString("/",path);
361 TKUICell *cell = (TKUICell*)mContainer->getInterfaceCell(fqn);
365 cell->setValue(value);
371 std::string DNEngine::getContentPath()
374 return mContainer->getContentPath();
379 std::string DNEngine::getUIPath()