diff options
-rw-r--r-- | server/src/Makefile.am | 24 | ||||
-rw-r--r-- | server/src/luaquerymapper.cc | 33 | ||||
-rw-r--r-- | server/src/queryhandler.cc | 196 | ||||
-rw-r--r-- | server/src/queryhandler.h | 31 | ||||
-rw-r--r-- | server/src/queryparser.cc | 33 | ||||
-rw-r--r-- | server/src/saxparser.cc | 7 | ||||
-rw-r--r-- | server/src/saxparser.h | 1 | ||||
-rw-r--r-- | server/src/tostring.cc | 4 | ||||
-rw-r--r-- | server/src/uid.cc | 2 |
9 files changed, 290 insertions, 41 deletions
diff --git a/server/src/Makefile.am b/server/src/Makefile.am index 251560b..7b66663 100644 --- a/server/src/Makefile.am +++ b/server/src/Makefile.am @@ -47,3 +47,27 @@ EXTRA_DIST = \ tcpsocket.h \ tostring.h \ uid.h + +TESTFILES = \ + test_queryhandler \ + test_queryparser \ + test_luaquerymapper + +TESTLOGS = `for F in ${TESTFILES}; do echo $$F.log; done` + +test: $(TESTFILES) + @echo "All tests done." + +test_clean: + rm -f $(TESTFILES) + +test_queryhandler: queryhandler.cc + @../../tools/test queryhandler.cc tcpsocket.cc exception.cc tostring.cc uid.cc log.cc + +test_queryparser: queryparser.cc + @../../tools/test queryparser.cc queryhandler.cc tcpsocket.cc exception.cc tostring.cc uid.cc log.cc saxparser.cc -lexpat + +test_luaquerymapper: luaquerymapper.cc + @../../tools/test luaquerymapper.cc queryparser.cc queryhandler.cc tcpsocket.cc exception.cc tostring.cc uid.cc log.cc saxparser.cc -lexpat $(LUA_LIBS) + +CLEANFILES = $(TESTFILES) $(TESTLOGS) diff --git a/server/src/luaquerymapper.cc b/server/src/luaquerymapper.cc index f4f6f20..be18742 100644 --- a/server/src/luaquerymapper.cc +++ b/server/src/luaquerymapper.cc @@ -105,28 +105,33 @@ std::string LUAQueryMapper::map(const std::string &mapper) #ifdef TEST_LUAQUERYMAPPER +#include "queryhandler.h" +#include "queryparser.h" + int main() { - QueryResult res; + TCPSocket s; + s.connect("localhost", 11108); + + QueryHandler qh(&s, "2003791613"); - QueryResult group1; - group1.values["dims"] = "42"; + Query q1("lensmeter", "lensmeter"); + qh.addQuery(q1); - QueryResult group2; - group2.values["foo"] = "bar"; - group2.values["bar"] = "foo"; - group2.groups["fnuller"] = group1; + std::string res = qh.exec(); + + printf("%s\n", res.c_str()); - res.values["dims"] = "42"; - res.groups["dimmer"] = group2; + QueryParser e(res); + e.parse(); - LUAQueryMapper mapper(res); + LUAQueryMapper mapper(e.result); - std::string luamap = "return dimmer.fnuller.dims * 2 + dims"; - printf("%s\n", mapper.map(luamap).c_str()); + std::string luamap = "return right.sphere"; + printf("%s : %s\n", luamap.c_str(), mapper.map(luamap).c_str()); - luamap = "return math.sin(dimmer.fnuller.dims * 2 + dims)"; - printf("%s\n", mapper.map(luamap).c_str()); + luamap = "return math.sin(right.cyl) * 2"; + printf("%s : %s\n", luamap.c_str(), mapper.map(luamap).c_str()); return 0; } diff --git a/server/src/queryhandler.cc b/server/src/queryhandler.cc index 16db038..e21d820 100644 --- a/server/src/queryhandler.cc +++ b/server/src/queryhandler.cc @@ -26,6 +26,200 @@ */ #include "queryhandler.h" -QueryHandler::QueryHandler() +// For time +#include <time.h> + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +// For getpid +#include <unistd.h> +#include <sys/types.h> + +// For time +#include <time.h> + +// For strerror and errno +#include <errno.h> + +// For socket and friends +#include <sys/socket.h> +#include <arpa/inet.h> +#include <net/if.h> +#include <netinet/in.h> + +// For ioctl +#include <sys/ioctl.h> + +typedef struct { + in_addr_t ip; + time_t time; + pid_t pid; + unsigned short int count; +} UID; + + +#define SIOCGIFCONF 0x8912 // get iface list + +static in_addr_t getIP(char *interface) { + in_addr_t ret = 0; + int numreqs = 30, sd, n; + struct ifconf ifc; + struct ifreq *ifr; + struct in_addr *ia; + + sd = socket(AF_INET, SOCK_STREAM, 0); + if(sd == -1) { + // throw Pentominos::UIDCouldNotConnectException(strerror(errno)); + } + + ifc.ifc_buf = NULL; + ifc.ifc_len = sizeof(struct ifreq) * numreqs; + + ifc.ifc_buf = (char*)malloc(ifc.ifc_len); + if(ifc.ifc_buf == NULL) { + // throw Pentominos::UIDOutOfMemoryException(); + } + + if (ioctl(sd, SIOCGIFCONF, &ifc) < 0) { + // throw Pentominos::UIDInterfaceListException(strerror(errno)); + } + + ifr = ifc.ifc_req; + for (n = 0; n < ifc.ifc_len; n += sizeof(struct ifreq)) { + ia = (struct in_addr *)((ifr->ifr_ifru.ifru_addr.sa_data)+2); + if(!strcmp(ifr->ifr_ifrn.ifrn_name, interface)) { + ret = *(in_addr_t*)ia; + } + ifr++; + } + + if(!ret) { // Still no interface... We're fucked! + // throw Pentominos::UIDInterfaceException(interface); + } + + free(ifc.ifc_buf); + return ret; +} + + +static unsigned short counter = 0; +static unsigned short getCounter() +{ + return counter++; +} + +static UID uid = {0,0,0,0}; +static std::string getUID(char *interface) +{ + if(!uid.ip) uid.ip = getIP(interface); + + time_t t = time(NULL); + if(uid.time != t) counter = 0; // If time differes, reset the counter + uid.time = t; // We need this value every time. + + if(!uid.pid) uid.pid = getpid(); + + uid.count = getCounter(); + + char buf[32]; + sprintf(buf, "%08x%08x%04x%04x", uid.ip, (unsigned int)uid.time, uid.pid, uid.count); + return std::string(buf); } + + +QueryHandler::QueryHandler(TCPSocket *socket, std::string cpr) +{ + this->cpr = cpr; + this->socket = socket; +} + +void QueryHandler::addQuery(Query &query) +{ + queries.push_back(query); +} + +std::string QueryHandler::exec() +{ + time_t timestamp = time(NULL); + std::string uid = getUID("eth0"); + + char buf[512]; + char header[] = + "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + "<artefact xmlns=\"http://www.aasimon.org/pentominos\"\n" + " xmlns:pentominos=\"http://www.aasimon.org/pentominos\"\n" + " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n" + " xsi:schemaLocation=\"http://www.aasimon.org/pentominos schema.xsd\">\n"; + socket->write(header, strlen(header)); + + sprintf(buf, " <pentominos:entry cpr=\"%s\"\n" + " src_addr=\"%s\"\n" + " dst_addr=\"%s\"\n" + " timestamp=\"%d\"\n" + " uid=\"%s\"/>\n", + cpr.c_str(), + socket->srcaddr().c_str(), + socket->dstaddr().c_str(), + (unsigned int)timestamp, + uid.c_str()); + socket->write(buf, strlen(buf)); + + std::vector< Query >::iterator j = queries.begin(); + while(j != queries.end()) { + Query query = *j; + + sprintf(buf, " <pentominos:query format=\"pracroxml\"\n" + " device_id=\"%s\"\n" + " device_type=\"%s\"\n" + " filter=\"latest\"\n" + " location=\"all\"/>\n", + query.device_id.c_str(), + query.device_type.c_str()); + + socket->write(buf, strlen(buf)); + + j++; + } + + sprintf(buf, "</artefact>\n"); + socket->write(buf, strlen(buf)); + + // Terminate + socket->write("\0", 1); + + // Wait for answer + char abuf[64]; + int res; + std::string answer; + do { + memset(abuf, 0, sizeof(abuf)); + res = socket->read(abuf, sizeof(abuf) - 1); + answer += abuf; + } while(res); + + return answer; +} + +#ifdef TEST_QUERYHANDLER + +int main() +{ + TCPSocket s; + s.connect("localhost", 11108); + + QueryHandler qh(&s, "2003791613"); + + Query q1("lensmeter", "lensmeter"); + qh.addQuery(q1); + + std::string res = qh.exec(); + + printf("%s\n", res.c_str()); + + return 0; +} + +#endif/*TEST_QUERYHANDLER*/ diff --git a/server/src/queryhandler.h b/server/src/queryhandler.h index 2de62ae..14e97c2 100644 --- a/server/src/queryhandler.h +++ b/server/src/queryhandler.h @@ -27,20 +27,41 @@ #ifndef __PRACRO_QUERYHANDLER_H__ #define __PRACRO_QUERYHANDLER_H__ -class Query {}; +#include "tcpsocket.h" + +#include <vector> +#include <string> + +/** + * Query specific values. This is the in-memory representation of a query transaction. + */ +class Query { +public: + Query(std::string id, std::string type) : + device_id(id), device_type(type) {} + std::string device_id; + std::string device_type; +}; + /** * This class handles the query of external data. */ class QueryHandler { public: - QueryHandler(); + QueryHandler(TCPSocket *socket, std::string cpr); // Add a query to the query queue - void addQuery(Query &query) {} + void addQuery(Query &query); + + // Execute all queries. + std::string exec(); + +private: + TCPSocket *socket; + std::string cpr; - // Execute all queries in parallel, for speed improv. - void exec() {} + std::vector< Query > queries; }; #endif/*__PRACRO_QUERYHANDLER_H__*/ diff --git a/server/src/queryparser.cc b/server/src/queryparser.cc index 38e3037..34c7aa3 100644 --- a/server/src/queryparser.cc +++ b/server/src/queryparser.cc @@ -62,7 +62,9 @@ int QueryParser::readData(char *data, size_t size) return len; } -#ifdef TEST_EXTERNALDATAQUERYPARSER +#ifdef TEST_QUERYPARSER + +#include "queryhandler.h" static std::string loadresultstring(QueryResult &res, std::string group = "") { @@ -84,24 +86,21 @@ static std::string loadresultstring(QueryResult &res, std::string group = "") return s; } -char xml[] = - "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" - "<group name=\"dims\">\n" - " <value name=\"fisk\" value=\"42\"/>" - " <value name=\"futte\" value=\"bamse\"/>" - " <group name=\"dims2\">\n" - " <value name=\"fisk2\" value=\"42\"/>" - " <value name=\"futte2\" value=\"bamse\"/>" - " </group>\n" - " <group name=\"dims3\">\n" - " <value name=\"fisk3\" value=\"42\"/>" - " <value name=\"futte3\" value=\"bamse\"/>" - " </group>\n" - "</group>\n"; - int main() { - QueryParser e(xml); + TCPSocket s; + s.connect("localhost", 11108); + + QueryHandler qh(&s, "2003791613"); + + Query q1("lensmeter", "lensmeter"); + qh.addQuery(q1); + + std::string res = qh.exec(); + + printf("%s\n", res.c_str()); + + QueryParser e(res); e.parse(); printf("%s\n", loadresultstring(e.result).c_str()); diff --git a/server/src/saxparser.cc b/server/src/saxparser.cc index e0d849a..2eabf38 100644 --- a/server/src/saxparser.cc +++ b/server/src/saxparser.cc @@ -68,6 +68,11 @@ SAXParser::SAXParser() XML_SetElementHandler(p, start_hndl, end_hndl); } +SAXParser::~SAXParser() +{ + XML_ParserFree(p); +} + int SAXParser::parse() { char buf[32]; @@ -77,7 +82,7 @@ int SAXParser::parse() len = readData(buf, sizeof(buf) - 1); if (! XML_Parse(p, buf, len, len == 0)) { fprintf(stderr, "Parse error at line %d:\n%s\n", - XML_GetCurrentLineNumber(p), + (int)XML_GetCurrentLineNumber(p), XML_ErrorString(XML_GetErrorCode(p))); return -1; } diff --git a/server/src/saxparser.h b/server/src/saxparser.h index c03b281..e15b38c 100644 --- a/server/src/saxparser.h +++ b/server/src/saxparser.h @@ -34,6 +34,7 @@ class SAXParser { public: SAXParser(); + virtual ~SAXParser(); int parse(); diff --git a/server/src/tostring.cc b/server/src/tostring.cc index bde5498..3179e00 100644 --- a/server/src/tostring.cc +++ b/server/src/tostring.cc @@ -70,7 +70,7 @@ std::string toString(short unsigned int su) std::string toString(int li) { char buf[32]; - sprintf(buf, "%ld", li); + sprintf(buf, "%ld", (long int)li); std::string out = buf; return buf; } @@ -78,7 +78,7 @@ std::string toString(int li) std::string toString(unsigned int lu) { char buf[32]; - sprintf(buf, "%lu", lu); + sprintf(buf, "%lu", (long unsigned int)lu); std::string out = buf; return buf; } diff --git a/server/src/uid.cc b/server/src/uid.cc index f9f98ae..7cf3bb8 100644 --- a/server/src/uid.cc +++ b/server/src/uid.cc @@ -58,6 +58,6 @@ std::string UID::toString() { // std::string uid; char buf[256]; - sprintf(buf, "%08x%04x%02x", time, pid, cnt); + sprintf(buf, "%08x%04x%02x", (unsigned int)time, pid, cnt); return buf; } |