summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--3rdParty/Lua/SConscript6
-rw-r--r--Sluift/client_test.lua32
-rw-r--r--Sluift/linit.c40
-rw-r--r--Sluift/sluift.cpp114
-rw-r--r--Swiften/Client/Client.cpp4
-rw-r--r--Swiften/Client/Client.h2
-rw-r--r--Swiften/Queries/Responders/SoftwareVersionResponder.cpp5
-rw-r--r--Swiften/Queries/Responders/SoftwareVersionResponder.h3
8 files changed, 158 insertions, 48 deletions
diff --git a/3rdParty/Lua/SConscript b/3rdParty/Lua/SConscript
index 9d0315e..f69c3cd 100644
--- a/3rdParty/Lua/SConscript
+++ b/3rdParty/Lua/SConscript
@@ -8,12 +8,14 @@ if env.get("LUA_BUNDLED", False) :
if env["SCONS_STAGE"] == "flags" :
cppdefines = []
+ if not env["optimize"] :
+ cppdefines.append("LUA_USE_APICHECK")
if env["PLATFORM"] == "win32" :
pass
elif env["PLATFORM"] == "darwin" :
- cppdefines = ["LUA_USE_POSIX", "LUA_USE_DLOPEN"]
+ cppdefines += ["LUA_USE_POSIX", "LUA_USE_DLOPEN"]
else :
- cppdefines = ["LUA_USE_POSIX", "LUA_USE_DLOPEN"]
+ cppdefines += ["LUA_USE_POSIX", "LUA_USE_DLOPEN"]
env["LUA_FLAGS"] = {
"CPPDEFINES": cppdefines,
diff --git a/Sluift/client_test.lua b/Sluift/client_test.lua
new file mode 100644
index 0000000..afb8147
--- /dev/null
+++ b/Sluift/client_test.lua
@@ -0,0 +1,32 @@
+require "sluift"
+
+--sluift.debug = true
+client1_jid = os.getenv("SWIFT_CLIENTTEST_JID") .. "/Client1"
+client2_jid = os.getenv("SWIFT_CLIENTTEST_JID") .. "/Client2"
+password = os.getenv("SWIFT_CLIENTTEST_PASS")
+
+print "Connecting client 1"
+client1 = sluift.connect(client1_jid, password)
+client1:send_presence("I'm here")
+
+print "Connecting client 2"
+client2 = sluift.connect(client2_jid, password)
+client2:send_presence("I'm here")
+
+print "Checking version of client 2 from client 1"
+client2:set_version({name = "Sluift Test", version = "1.0"})
+client2_version = client1:get_version(client2_jid)
+assert(client2_version["name"] == "Sluift Test")
+assert(client2_version["version"] == "1.0")
+
+print "Sending message from client 1 to client 2"
+client1:send_message(client2_jid, "Hello")
+received_message = client2:for_event(function(event)
+ if event["type"] == "message" and event["from"] == client1_jid then
+ return event["body"]
+ end
+ end)
+assert(received_message == "Hello")
+
+client1:disconnect()
+client2:disconnect()
diff --git a/Sluift/linit.c b/Sluift/linit.c
deleted file mode 100644
index 4cb4c26..0000000
--- a/Sluift/linit.c
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
-** $Id: linit.c,v 1.14.1.1 2007/12/27 13:02:25 roberto Exp $
-** Initialization of libraries for lua.c
-** See Copyright Notice in lua.h
-*/
-
-
-#define linit_c
-#define LUA_LIB
-
-#include "lua.h"
-
-#include "lualib.h"
-#include "lauxlib.h"
-#include "sluift.h"
-
-
-static const luaL_Reg lualibs[] = {
- {"", luaopen_base},
- {LUA_LOADLIBNAME, luaopen_package},
- {LUA_TABLIBNAME, luaopen_table},
- {LUA_IOLIBNAME, luaopen_io},
- {LUA_OSLIBNAME, luaopen_os},
- {LUA_STRLIBNAME, luaopen_string},
- {LUA_MATHLIBNAME, luaopen_math},
- {LUA_DBLIBNAME, luaopen_debug},
- {"sluift", luaopen_sluift},
- {NULL, NULL}
-};
-
-
-LUALIB_API void luaL_openlibs (lua_State *L) {
- const luaL_Reg *lib = lualibs;
- for (; lib->func; lib++) {
- lua_pushcfunction(L, lib->func);
- lua_pushstring(L, lib->name);
- lua_call(L, 1, 0);
- }
-}
-
diff --git a/Sluift/sluift.cpp b/Sluift/sluift.cpp
index 5a9fbd5..895d90d 100644
--- a/Sluift/sluift.cpp
+++ b/Sluift/sluift.cpp
@@ -11,6 +11,7 @@ extern "C" {
#include <iostream>
#include <string>
+#include <deque>
#include <Swiften/Client/Client.h>
#include <Swiften/Client/ClientXMLTracer.h>
@@ -51,6 +52,8 @@ class SluiftClient {
SluiftClient(const JID& jid, const std::string& password, bool debug = false) : tracer(NULL) {
client = new Client(jid, password, &networkFactories);
client->setAlwaysTrustCertificates();
+ client->onMessageReceived.connect(boost::bind(&SluiftClient::handleIncomingEvent, this, _1));
+ client->onPresenceReceived.connect(boost::bind(&SluiftClient::handleIncomingEvent, this, _1));
if (debug) {
tracer = new ClientXMLTracer(client);
}
@@ -79,6 +82,10 @@ class SluiftClient {
client->sendMessage(message);
}
+ void sendPresence(const std::string& status) {
+ client->sendPresence(boost::make_shared<Presence>(status));
+ }
+
void disconnect() {
client->disconnect();
while (client->isActive()) {
@@ -86,6 +93,10 @@ class SluiftClient {
}
}
+ void setSoftwareVersion(const std::string& name, const std::string& version, const std::string& os) {
+ client->setSoftwareVersion(name, version, os);
+ }
+
boost::optional<SoftwareVersion> getSoftwareVersion(const JID& jid) {
GetSoftwareVersionRequest::ref request = GetSoftwareVersionRequest::create(jid, client->getIQRouter());
request->onResponse.connect(boost::bind(&SluiftClient::handleSoftwareVersionResponse, this, _1, _2));
@@ -98,7 +109,31 @@ class SluiftClient {
return softwareVersion;
}
+ Stanza::ref getNextEvent() {
+ if (client->isActive() && !pendingEvents.empty()) {
+ Stanza::ref event = pendingEvents.front();
+ pendingEvents.pop_front();
+ return event;
+ }
+ while (client->isActive() && pendingEvents.empty()) {
+ processEvents();
+ }
+ if (client->isActive()) {
+ assert(!pendingEvents.empty());
+ Stanza::ref event = pendingEvents.front();
+ pendingEvents.pop_front();
+ return event;
+ }
+ else {
+ return Stanza::ref();
+ }
+ }
+
private:
+ void handleIncomingEvent(Stanza::ref stanza) {
+ pendingEvents.push_back(stanza);
+ }
+
void processEvents() {
eventLoop.runUntilEvents();
}
@@ -120,6 +155,7 @@ class SluiftClient {
ClientXMLTracer* tracer;
boost::optional<SoftwareVersion> softwareVersion;
ErrorPayload::ref error;
+ std::deque<Stanza::ref> pendingEvents;
};
@@ -141,6 +177,19 @@ static int sluift_client_disconnect(lua_State *L) {
return 0;
}
+static int sluift_client_set_version(lua_State *L) {
+ SluiftClient* client = getClient(L);
+ luaL_checktype(L, 2, LUA_TTABLE);
+ lua_getfield(L, 2, "name");
+ const char* rawName = lua_tostring(L, -1);
+ lua_getfield(L, 2, "version");
+ const char* rawVersion = lua_tostring(L, -1);
+ lua_getfield(L, 2, "os");
+ const char* rawOS = lua_tostring(L, -1);
+ client->setSoftwareVersion(rawName ? rawName : "", rawVersion ? rawVersion : "", rawOS ? rawOS : "");
+ lua_pop(L, 3);
+ return 0;
+}
static int sluift_client_get_version(lua_State *L) {
SluiftClient* client = getClient(L);
@@ -167,6 +216,68 @@ static int sluift_client_send_message(lua_State *L) {
return 0;
}
+static int sluift_client_send_presence(lua_State *L) {
+ getClient(L)->sendPresence(std::string(luaL_checkstring(L, 2)));
+ return 0;
+}
+
+static int sluift_client_for_event (lua_State *L) {
+ SluiftClient* client = getClient(L);
+ luaL_checktype(L, 2, LUA_TFUNCTION);
+ while (true) {
+ Stanza::ref event = client->getNextEvent();
+ if (!event) {
+ // We got disconnected
+ lua_pushnil(L);
+ lua_pushliteral(L, "disconnected");
+ return 2;
+ }
+ else {
+ // Push the function on the stack
+ lua_pushvalue(L, 2);
+
+ bool emitEvent = false;
+ if (Message::ref message = boost::dynamic_pointer_cast<Message>(event)) {
+ lua_createtable(L, 0, 3);
+ lua_pushliteral(L, "message");
+ lua_setfield(L, -2, "type");
+ lua_pushstring(L, message->getFrom().toString().c_str());
+ lua_setfield(L, -2, "from");
+ lua_pushstring(L, message->getBody().c_str());
+ lua_setfield(L, -2, "body");
+ emitEvent = true;
+ }
+ else if (Presence::ref presence = boost::dynamic_pointer_cast<Presence>(event)) {
+ lua_createtable(L, 0, 3);
+ lua_pushliteral(L, "presence");
+ lua_setfield(L, -2, "type");
+ lua_pushstring(L, presence->getFrom().toString().c_str());
+ lua_setfield(L, -2, "from");
+ lua_pushstring(L, presence->getStatus().c_str());
+ lua_setfield(L, -2, "status");
+ emitEvent = true;
+ }
+ else {
+ assert(false);
+ }
+ if (emitEvent) {
+ int oldTop = lua_gettop(L) - 2;
+ lua_call(L, 1, LUA_MULTRET);
+ int returnValues = lua_gettop(L) - oldTop;
+ if (returnValues > 0) {
+ lua_remove(L, -1 - returnValues);
+ return returnValues;
+ }
+ }
+ else {
+ // Remove the function from the stack again, since
+ // we're not calling the function
+ lua_pop(L, 1);
+ }
+ }
+ }
+}
+
static int sluift_client_gc (lua_State *L) {
SluiftClient* client = getClient(L);
delete client;
@@ -178,7 +289,10 @@ static const luaL_reg sluift_client_functions[] = {
{"is_connected", sluift_client_is_connected},
{"disconnect", sluift_client_disconnect},
{"send_message", sluift_client_send_message},
+ {"send_presence", sluift_client_send_presence},
+ {"set_version", sluift_client_set_version},
{"get_version", sluift_client_get_version},
+ {"for_event", sluift_client_for_event},
{"__gc", sluift_client_gc},
{NULL, NULL}
};
diff --git a/Swiften/Client/Client.cpp b/Swiften/Client/Client.cpp
index 904f722..7918c46 100644
--- a/Swiften/Client/Client.cpp
+++ b/Swiften/Client/Client.cpp
@@ -93,8 +93,8 @@ XMPPRoster* Client::getRoster() const {
return roster;
}
-void Client::setSoftwareVersion(const std::string& name, const std::string& version) {
- softwareVersionResponder->setVersion(name, version);
+void Client::setSoftwareVersion(const std::string& name, const std::string& version, const std::string& os) {
+ softwareVersionResponder->setVersion(name, version, os);
}
void Client::requestRoster() {
diff --git a/Swiften/Client/Client.h b/Swiften/Client/Client.h
index 868c9c4..d5db1ac 100644
--- a/Swiften/Client/Client.h
+++ b/Swiften/Client/Client.h
@@ -56,7 +56,7 @@ namespace Swift {
*
* This will be used to respond to version queries from other entities.
*/
- void setSoftwareVersion(const std::string& name, const std::string& version);
+ void setSoftwareVersion(const std::string& name, const std::string& version, const std::string& os);
/**
* Returns a representation of the roster.
diff --git a/Swiften/Queries/Responders/SoftwareVersionResponder.cpp b/Swiften/Queries/Responders/SoftwareVersionResponder.cpp
index 0b8362c..445dcc7 100644
--- a/Swiften/Queries/Responders/SoftwareVersionResponder.cpp
+++ b/Swiften/Queries/Responders/SoftwareVersionResponder.cpp
@@ -12,13 +12,14 @@ namespace Swift {
SoftwareVersionResponder::SoftwareVersionResponder(IQRouter* router) : GetResponder<SoftwareVersion>(router) {
}
-void SoftwareVersionResponder::setVersion(const std::string& client, const std::string& version) {
+void SoftwareVersionResponder::setVersion(const std::string& client, const std::string& version, const std::string& os) {
this->client = client;
this->version = version;
+ this->os = os;
}
bool SoftwareVersionResponder::handleGetRequest(const JID& from, const JID&, const std::string& id, boost::shared_ptr<SoftwareVersion>) {
- sendResponse(from, id, boost::shared_ptr<SoftwareVersion>(new SoftwareVersion(client, version)));
+ sendResponse(from, id, boost::shared_ptr<SoftwareVersion>(new SoftwareVersion(client, version, os)));
return true;
}
diff --git a/Swiften/Queries/Responders/SoftwareVersionResponder.h b/Swiften/Queries/Responders/SoftwareVersionResponder.h
index f6a3d52..cbda54c 100644
--- a/Swiften/Queries/Responders/SoftwareVersionResponder.h
+++ b/Swiften/Queries/Responders/SoftwareVersionResponder.h
@@ -16,7 +16,7 @@ namespace Swift {
public:
SoftwareVersionResponder(IQRouter* router);
- void setVersion(const std::string& client, const std::string& version);
+ void setVersion(const std::string& client, const std::string& version, const std::string& os = "");
private:
virtual bool handleGetRequest(const JID& from, const JID& to, const std::string& id, boost::shared_ptr<SoftwareVersion> payload);
@@ -24,5 +24,6 @@ namespace Swift {
private:
std::string client;
std::string version;
+ std::string os;
};
}