summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--munia.html6
-rw-r--r--src/Makefile.am6
-rw-r--r--src/muniad.cc430
-rw-r--r--src/task_proto.cc347
-rw-r--r--src/task_proto.h44
5 files changed, 414 insertions, 419 deletions
diff --git a/munia.html b/munia.html
index 2eb8438..46feb61 100644
--- a/munia.html
+++ b/munia.html
@@ -100,7 +100,7 @@ function get_appropriate_ws_url()
//document.getElementById("create_task").style.display = '';
-/* lws-mirror protocol */
+/* lws-task protocol */
var down = 0;
var no_last = 1;
@@ -111,9 +111,9 @@ var color = "#000000";
var dragged = "";
if (BrowserDetect.browser == "Firefox") {
- socket_lm = new MozWebSocket(get_appropriate_ws_url(), "lws-mirror-protocol");
+ socket_lm = new MozWebSocket(get_appropriate_ws_url(), "lws-task-protocol");
} else {
- socket_lm = new WebSocket(get_appropriate_ws_url(), "lws-mirror-protocol");
+ socket_lm = new WebSocket(get_appropriate_ws_url(), "lws-task-protocol");
}
try {
diff --git a/src/Makefile.am b/src/Makefile.am
index b7ded17..9b20d05 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -9,11 +9,13 @@ muniad_CXXFLAGS = $(LIBWEBSOCKETS_CFLAGS)
muniad_SOURCES = \
muniad.cc \
http.cc \
- task.cc
+ task.cc \
+ task_proto.cc
EXTRA_DIST = \
http.h \
- task.h
+ task.h \
+ task_proto.h
################
# Test Section #
diff --git a/src/muniad.cc b/src/muniad.cc
index 8181f68..82311e7 100644
--- a/src/muniad.cc
+++ b/src/muniad.cc
@@ -36,310 +36,7 @@
#include <libwebsockets.h>
#include "http.h"
-#include "task.h"
-
-#define LWS_NO_FORK
-
-static int close_testing;
-
-/*
- * this is just an example of parsing handshake headers, you don't need this
- * in your code unless you will filter allowing connections by the header
- * content
- */
-
-static void dump_handshake_info(struct lws_tokens *lwst)
-{
- int n;
- static const char *token_names[WSI_TOKEN_COUNT] = {
- /*[WSI_TOKEN_GET_URI] =*/ "GET URI",
- /*[WSI_TOKEN_HOST] =*/ "Host",
- /*[WSI_TOKEN_CONNECTION] =*/ "Connection",
- /*[WSI_TOKEN_KEY1] =*/ "key 1",
- /*[WSI_TOKEN_KEY2] =*/ "key 2",
- /*[WSI_TOKEN_PROTOCOL] =*/ "Protocol",
- /*[WSI_TOKEN_UPGRADE] =*/ "Upgrade",
- /*[WSI_TOKEN_ORIGIN] =*/ "Origin",
- /*[WSI_TOKEN_DRAFT] =*/ "Draft",
- /*[WSI_TOKEN_CHALLENGE] =*/ "Challenge",
-
- /* new for 04 */
- /*[WSI_TOKEN_KEY] =*/ "Key",
- /*[WSI_TOKEN_VERSION] =*/ "Version",
- /*[WSI_TOKEN_SWORIGIN] =*/ "Sworigin",
-
- /* new for 05 */
- /*[WSI_TOKEN_EXTENSIONS] =*/ "Extensions",
-
- /* client receives these */
- /*[WSI_TOKEN_ACCEPT] =*/ "Accept",
- /*[WSI_TOKEN_NONCE] =*/ "Nonce",
- /*[WSI_TOKEN_HTTP] =*/ "Http",
- /*[WSI_TOKEN_MUXURL] =*/ "MuxURL",
- };
-
- for (n = 0; n < WSI_TOKEN_COUNT; n++) {
- if (lwst[n].token == NULL || lwst[n].token_len == 0) continue;
- fprintf(stderr, " %s = ", token_names[n]);
- if(fwrite(lwst[n].token, 1, lwst[n].token_len, stderr)) {}
- fprintf(stderr, "\n");
- }
-}
-
-
-/* lws-mirror_protocol */
-
-#define MAX_MESSAGE_QUEUE 1024
-
-struct per_session_data__lws_mirror {
- struct libwebsocket *wsi;
- int ringbuffer_tail;
-};
-
-struct a_message {
- void *payload;
- size_t len;
-};
-
-typedef std::list<struct libwebsocket*> ClientList;
-
-static struct a_message ringbuffer[MAX_MESSAGE_QUEUE];
-static int ringbuffer_head;
-static ClientList clientlist;
-static int id_count = 0;
-static int callback_lws_mirror(struct libwebsocket_context * context,
- struct libwebsocket *wsi,
- enum libwebsocket_callback_reasons reason,
- void *user, void *in, size_t len)
-{
- int n;
- struct per_session_data__lws_mirror *pss = (struct per_session_data__lws_mirror *)user;
-
- printf("Current number of clients: %d\n", clientlist.size());
-
- switch (reason) {
-
- case LWS_CALLBACK_ESTABLISHED:
- {
- fprintf(stderr, "callback_lws_mirror: LWS_CALLBACK_ESTABLISHED\n");
- pss->ringbuffer_tail = ringbuffer_head;
- pss->wsi = wsi;
- clientlist.push_back(wsi);
-
- // send all current tasks
- char buf[32];
- std::string init_str;
- TaskList::iterator it;
- for(it = tasklist.begin(); it != tasklist.end(); it++) {
- struct task t = *it;
-
- sprintf(buf, "add %d %s %s %d %d;",
- t.id, t.title.c_str(), t.desc.c_str(), t.x, t.y);
- init_str.append(buf);
- }
-
- libwebsocket_write(wsi, (unsigned char*) init_str.data(), init_str.length(), LWS_WRITE_TEXT);
-
- }
- break;
-
- case LWS_CALLBACK_CLOSED:
- {
- printf("Closing connection\n");
- clientlist.remove(wsi);
- }
-
- case LWS_CALLBACK_SERVER_WRITEABLE:
- {
- printf("LWS_CALLBACK_SERVER_WRITEABLE\n");
-
- if(close_testing) break;
-
- if(pss->ringbuffer_tail != ringbuffer_head) {
- n = libwebsocket_write(wsi, (unsigned char *)
- ringbuffer[pss->ringbuffer_tail].payload +
- LWS_SEND_BUFFER_PRE_PADDING,
- ringbuffer[pss->ringbuffer_tail].len,
- LWS_WRITE_TEXT);
- if(n < 0) {
- fprintf(stderr, "ERROR writing to socket");
- exit(1);
- }
-
- if(pss->ringbuffer_tail == (MAX_MESSAGE_QUEUE - 1)) pss->ringbuffer_tail = 0;
- else pss->ringbuffer_tail++;
-
- if(((ringbuffer_head - pss->ringbuffer_tail) % MAX_MESSAGE_QUEUE) < (MAX_MESSAGE_QUEUE - 15))
- libwebsocket_rx_flow_control(wsi, 1);
-
- libwebsocket_callback_on_writable(context, wsi);
- }
- }
- break;
-
- case LWS_CALLBACK_BROADCAST:
- printf("LWS_CALLBACK_BROADCAST\n");
- n = libwebsocket_write(wsi, (unsigned char*)in, len, LWS_WRITE_TEXT);
- if (n < 0) fprintf(stderr, "mirror write failed\n");
- break;
-
- case LWS_CALLBACK_RECEIVE:
- {
- printf("LWS_CALLBACK_RECEIVE\n");
-
- printf("%s\n", (char*)in);
- std::string data;
- data.append((char*)in, len);
-
-
- struct a_message &msg = ringbuffer[ringbuffer_head];
- if(msg.payload) {
- free(msg.payload);
- msg.payload = NULL;
- }
-
- char* buf = (char*) malloc(1024);
- int buf_len = 0;
-
- std::string cmd = data.substr(0, data.find(' '));
- printf("Cmd: %s\n", cmd.c_str());
-
- if(cmd == "add") {
- printf("Handling add cmd:\n");
- int offset = cmd.length() + 1;
- std::string title = data.substr(offset, data.find(' ', offset) - offset);
- offset += title.length() + 1;
- std::string desc = data.substr(offset, data.find(' ', offset) - offset);
- offset += desc.length() + 1;
- std::string x_str = data.substr(offset, data.find(' ', offset) - offset);
- int x = atoi(x_str.c_str());
- offset += x_str.length() + 1;
- std::string y_str = data.substr(offset, data.find(' ', offset) - offset);
- int y = atoi(y_str.c_str());
-
- struct task t;
- t.x = x;
- t.y = y;
- t.title = title;
- t.desc = desc;
- t.id = id_count; id_count++;
- tasklist.push_back(t);
-
- buf_len = sprintf(buf, "add %d %s %s %d %d;",
- t.id, t.title.c_str(), t.desc.c_str(),
- t.x, t.y);
-
- printf("Adding task: %s\n", buf);
-
- } else if(cmd == "del") {
- printf("Delete\n");
- int offset = cmd.length() + 1;
- std::string id_str = data.substr(offset, data.find(' ', offset) - offset);
- int id = atoi(id_str.c_str());
- printf("Deleting task with id %d\n", id);
-
- bool id_found = false;
- TaskList::iterator it;
- for(it = tasklist.begin(); it != tasklist.end(); it++) {
- struct task t = *it;
- if(t.id == id) {
- id_found = true;
- tasklist.erase(it);
- break;
- }
- }
-
- if(!id_found) {
- printf("\t!!!Could not locate task with id %d\n", id);
- }
-
- buf_len = sprintf(buf, "del %d;", id);
- printf("Deleting task: %s\n", buf);
-
- } else if(cmd == "move") {
- printf("Move\n");
-
- int offset = cmd.length() + 1;
- std::string s_id = data.substr(offset, data.find(' ', offset) - offset);
- int id = atoi(s_id.c_str());
- offset += s_id.length() + 1;
- std::string x_str = data.substr(offset, data.find(' ', offset) - offset);
- int x = atoi(x_str.c_str());
- offset += x_str.length() + 1;
- std::string y_str = data.substr(offset, data.find(' ', offset) - offset);
- int y = atoi(y_str.c_str());
-
- printf("Moving task with id %d to (%d,%d)\n", id, x, y);
-
- bool id_found = false;
- TaskList::iterator it;
- for(it = tasklist.begin(); it != tasklist.end(); it++) {
- struct task t = *it;
- if(t.id == id) {
- id_found = true;
- t.x = x;
- t.y = y;
- break;
- }
- }
-
- if(!id_found) {
- printf("\t!!!Could not locate task with id %d\n", id);
- }
-
- buf_len = sprintf(buf, "move %d %d %d;", id, x / 300 * 300, y);
- printf("Moving task: %s\n", buf);
- } else if(cmd == "update") {
- printf("Update\n");
- } else if(cmd == "d") {
- memcpy(buf, in, len);
- buf_len = len;
- }
- else { // unknown command
- printf("Unknown command :(\n");
- break;
- }
-
-// msg.payload = malloc(LWS_SEND_BUFFER_PRE_PADDING + len + LWS_SEND_BUFFER_POST_PADDING);
-// msg.len = len;
-// memcpy((char *)msg.payload + LWS_SEND_BUFFER_PRE_PADDING, in, len);
-// if(ringbuffer_head == (MAX_MESSAGE_QUEUE - 1)) ringbuffer_head = 0;
-// else ringbuffer_head++;
-
- msg.payload = malloc(LWS_SEND_BUFFER_PRE_PADDING + buf_len
- + LWS_SEND_BUFFER_POST_PADDING);
- msg.len = buf_len;
- memcpy((char *)msg.payload + LWS_SEND_BUFFER_PRE_PADDING,
- buf, buf_len);
- if(ringbuffer_head == (MAX_MESSAGE_QUEUE - 1)) ringbuffer_head = 0;
- else ringbuffer_head++;
-
-
- if(((ringbuffer_head - pss->ringbuffer_tail) % MAX_MESSAGE_QUEUE) > (MAX_MESSAGE_QUEUE - 10))
- libwebsocket_rx_flow_control(wsi, 0);
-
- libwebsocket_callback_on_writable_all_protocol(libwebsockets_get_protocol(wsi));
- }
- break;
- /*
- * this just demonstrates how to use the protocol filter. If you won't
- * study and reject connections based on header content, you don't need
- * to handle this callback
- */
-
- case LWS_CALLBACK_FILTER_PROTOCOL_CONNECTION:
- printf("LWS_CALLBACK_FILTER_PROTOCOL_CONNECTION\n");
- dump_handshake_info((struct lws_tokens *)(long)user);
- /* you could return non-zero here and kill the connection */
- break;
-
- default:
- break;
- }
-
- return 0;
-}
-
+#include "task_proto.h"
/* list of supported protocols and callbacks */
@@ -352,9 +49,9 @@ static struct libwebsocket_protocols protocols[] = {
0 /* per_session_data_size */
},
{
- "lws-mirror-protocol",
- callback_lws_mirror,
- sizeof(struct per_session_data__lws_mirror)
+ "lws-task-protocol",
+ callback_lws_task,
+ sizeof(struct per_session_data__lws_task)
},
{
NULL, NULL, 0 /* End of list */
@@ -367,7 +64,6 @@ static struct option options[] = {
{ "ssl", no_argument, NULL, 's' },
{ "killmask", no_argument, NULL, 'k' },
{ "interface", required_argument, NULL, 'i' },
- { "closetest", no_argument, NULL, 'c' },
{ NULL, 0, 0, 0 }
};
@@ -375,30 +71,25 @@ int main(int argc, char **argv)
{
int n = 0;
const char *cert_path =
- LOCAL_RESOURCE_PATH"/libwebsockets-test-server.pem";
+ LOCAL_RESOURCE_PATH"/libwebsockets-test-server.pem";
const char *key_path =
- LOCAL_RESOURCE_PATH"/libwebsockets-test-server.key.pem";
- unsigned char buf[LWS_SEND_BUFFER_PRE_PADDING + 1024 +
- LWS_SEND_BUFFER_POST_PADDING];
+ LOCAL_RESOURCE_PATH"/libwebsockets-test-server.key.pem";
+
int port = 7681;
int use_ssl = 0;
struct libwebsocket_context *context;
int opts = 0;
char interface_name[128] = "";
const char * interface = NULL;
-#ifdef LWS_NO_FORK
-// unsigned int oldus = 0;
-#endif
fprintf(stderr, "libwebsockets test server\n"
- "(C) Copyright 2010-2011 Andy Green <andy@warmcat.com> "
- "licensed under LGPL2.1\n");
+ "(C) Copyright 2010-2011 Andy Green <andy@warmcat.com> "
+ "licensed under LGPL2.1\n");
- while (n >= 0) {
+ while(n >= 0) {
n = getopt_long(argc, argv, "ci:khsp:", options, NULL);
- if (n < 0)
- continue;
- switch (n) {
+ if(n < 0) continue;
+ switch(n) {
case 's':
use_ssl = 1;
break;
@@ -413,15 +104,8 @@ int main(int argc, char **argv)
interface_name[(sizeof interface_name) - 1] = '\0';
interface = interface_name;
break;
- case 'c':
- close_testing = 1;
- fprintf(stderr, " Close testing mode -- closes on "
- "client after 50 dumb increments"
- "and suppresses lws_mirror spam\n");
- break;
case 'h':
- fprintf(stderr, "Usage: test-server "
- "[--port=<p>] [--ssl]\n");
+ fprintf(stderr, "Usage: test-server [--port=<p>] [--ssl]\n");
exit(1);
}
}
@@ -430,98 +114,16 @@ int main(int argc, char **argv)
cert_path = key_path = NULL;
context = libwebsocket_create_context(port, interface, protocols,
- libwebsocket_internal_extensions,
- cert_path, key_path, -1, -1, opts);
+ libwebsocket_internal_extensions,
+ cert_path, key_path, -1, -1, opts);
if (context == NULL) {
fprintf(stderr, "libwebsocket init failed\n");
return -1;
}
- buf[LWS_SEND_BUFFER_PRE_PADDING] = 'x';
-
-#ifdef LWS_NO_FORK
-
- /*
- * This example shows how to work with no forked service loop
- */
-
- fprintf(stderr, " Using no-fork service loop\n");
-
- while (1) {
- /*
- * This example server does not fork or create a thread for
- * websocket service, it all runs in this single loop. So,
- * we have to give the websockets an opportunity to service
- * "manually".
- *
- * If no socket is needing service, the call below returns
- * immediately and quickly.
- */
-
- libwebsocket_service(context, 50);
- }
-
-#else
-
- /*
- * This example shows how to work with the forked websocket service loop
- */
-
- fprintf(stderr, " Using forked service loop\n");
-
- /*
- * This forks the websocket service action into a subprocess so we
- * don't have to take care about it.
- */
-
- n = libwebsockets_fork_service_loop(context);
- if (n < 0) {
- fprintf(stderr, "Unable to fork service loop %d\n", n);
- return 1;
- }
-
- while (1) {
-
- usleep(50000);
-
- /*
- * This broadcasts to all dumb-increment-protocol connections
- * at 20Hz.
- *
- * We're just sending a character 'x', in these examples the
- * callbacks send their own per-connection content.
- *
- * You have to send something with nonzero length to get the
- * callback actions delivered.
- *
- * We take care of pre-and-post padding allocation.
- */
-
- libwebsockets_broadcast(&protocols[PROTOCOL_DUMB_INCREMENT],
- &buf[LWS_SEND_BUFFER_PRE_PADDING], 1);
- }
-
-#endif
+ while (1) libwebsocket_service(context, 50);
libwebsocket_context_destroy(context);
return 0;
}
-
-#ifdef TEST_MUNIAD
-//Additional dependency files
-//deps:
-//Required cflags (autoconf vars may be used)
-//cflags:
-//Required link options (autoconf vars may be used)
-//libs:
-#include "test.h"
-
-TEST_BEGIN;
-
-// TODO: Put some testcode here (see test.h for usable macros).
-TEST_TRUE(false, "No tests yet!");
-
-TEST_END;
-
-#endif/*TEST_MUNIAD*/
diff --git a/src/task_proto.cc b/src/task_proto.cc
new file mode 100644
index 0000000..af1e31d
--- /dev/null
+++ b/src/task_proto.cc
@@ -0,0 +1,347 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set et sw=2 ts=2: */
+/***************************************************************************
+ * task_proto.cc
+ *
+ * Fri Feb 24 08:23:16 CET 2012
+ * Copyright 2012 Bent Bisballe Nyeng
+ * deva@aasimon.org
+ ****************************************************************************/
+
+/*
+ * This file is part of Munia.
+ *
+ * Munia is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Munia is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Munia; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+#include "task_proto.h"
+
+#include <stdio.h>
+#include <string.h>
+
+#include <queue>
+
+#include "task.h"
+
+static void dump_handshake_info(struct lws_tokens *lwst)
+{
+ int n;
+ static const char *token_names[WSI_TOKEN_COUNT] = {
+ /*[WSI_TOKEN_GET_URI] =*/ "GET URI",
+ /*[WSI_TOKEN_HOST] =*/ "Host",
+ /*[WSI_TOKEN_CONNECTION] =*/ "Connection",
+ /*[WSI_TOKEN_KEY1] =*/ "key 1",
+ /*[WSI_TOKEN_KEY2] =*/ "key 2",
+ /*[WSI_TOKEN_PROTOCOL] =*/ "Protocol",
+ /*[WSI_TOKEN_UPGRADE] =*/ "Upgrade",
+ /*[WSI_TOKEN_ORIGIN] =*/ "Origin",
+ /*[WSI_TOKEN_DRAFT] =*/ "Draft",
+ /*[WSI_TOKEN_CHALLENGE] =*/ "Challenge",
+
+ /* new for 04 */
+ /*[WSI_TOKEN_KEY] =*/ "Key",
+ /*[WSI_TOKEN_VERSION] =*/ "Version",
+ /*[WSI_TOKEN_SWORIGIN] =*/ "Sworigin",
+
+ /* new for 05 */
+ /*[WSI_TOKEN_EXTENSIONS] =*/ "Extensions",
+
+ /* client receives these */
+ /*[WSI_TOKEN_ACCEPT] =*/ "Accept",
+ /*[WSI_TOKEN_NONCE] =*/ "Nonce",
+ /*[WSI_TOKEN_HTTP] =*/ "Http",
+ /*[WSI_TOKEN_MUXURL] =*/ "MuxURL",
+ };
+
+ for (n = 0; n < WSI_TOKEN_COUNT; n++) {
+ if (lwst[n].token == NULL || lwst[n].token_len == 0) continue;
+ fprintf(stderr, " %s = ", token_names[n]);
+ if(fwrite(lwst[n].token, 1, lwst[n].token_len, stderr)) {}
+ fprintf(stderr, "\n");
+ }
+}
+
+#define MAX_MESSAGE_QUEUE 1024
+
+struct a_message {
+ void *payload;
+ size_t len;
+};
+
+typedef std::list<struct libwebsocket*> ClientList;
+
+std::queue<std::string> msgqueue;
+
+/*
+static struct a_message ringbuffer[MAX_MESSAGE_QUEUE];
+static int ringbuffer_head;
+*/
+
+static ClientList clientlist;
+static int id_count = 0;
+
+int callback_lws_task(struct libwebsocket_context * context,
+ struct libwebsocket *wsi,
+ enum libwebsocket_callback_reasons reason,
+ void *user, void *in, size_t len)
+{
+ int n;
+ struct per_session_data__lws_task *pss =
+ (struct per_session_data__lws_task *)user;
+
+ printf("Current number of clients: %d\n", clientlist.size());
+
+ switch (reason) {
+ printf("============= Reason %d\n", reason);
+ case LWS_CALLBACK_ESTABLISHED:
+ {
+ fprintf(stderr, "callback_lws_task: LWS_CALLBACK_ESTABLISHED\n");
+ // pss->ringbuffer_tail = ringbuffer_head;
+ pss->wsi = wsi;
+ clientlist.push_back(wsi);
+
+ // send all current tasks
+ char buf[32];
+ std::string init_str;
+ TaskList::iterator it;
+ for(it = tasklist.begin(); it != tasklist.end(); it++) {
+ struct task t = *it;
+
+ sprintf(buf, "add %d %s %s %d %d;",
+ t.id, t.title.c_str(), t.desc.c_str(), t.x, t.y);
+ init_str.append(buf);
+ }
+
+ std::string msg;
+ msg.append((size_t)LWS_SEND_BUFFER_PRE_PADDING, ' ');
+ msg.append(init_str);
+ msg.append((size_t)LWS_SEND_BUFFER_POST_PADDING, ' ');
+ msgqueue.push(msg);
+
+ /*
+ n = libwebsocket_write(wsi, (unsigned char*) init_str.data(),
+ init_str.length(), LWS_WRITE_TEXT);
+ if(n < 0) {
+ fprintf(stderr, "ERROR writing to socket");
+ exit(1);
+ }
+ */
+ libwebsocket_rx_flow_control(wsi, 1);
+ }
+ break;
+
+ case LWS_CALLBACK_CLOSED:
+ {
+ printf("Closing connection\n");
+ clientlist.remove(wsi);
+ }
+
+ case LWS_CALLBACK_SERVER_WRITEABLE:
+ {
+ printf("LWS_CALLBACK_SERVER_WRITEABLE\n");
+
+ // if(pss->ringbuffer_tail != ringbuffer_head) {
+ if(msgqueue.size() > 0) {
+ std::string msg = msgqueue.front();
+ msgqueue.pop();
+ n = libwebsocket_write(wsi, (unsigned char *)
+ msg.c_str() +
+ LWS_SEND_BUFFER_PRE_PADDING,
+ msg.length() - LWS_SEND_BUFFER_POST_PADDING - LWS_SEND_BUFFER_PRE_PADDING,
+ LWS_WRITE_TEXT);
+ if(n < 0) {
+ fprintf(stderr, "ERROR writing to socket");
+ exit(1);
+ }
+
+ /*
+ if(((ringbuffer_head - pss->ringbuffer_tail) % MAX_MESSAGE_QUEUE)
+ < (MAX_MESSAGE_QUEUE - 15))
+ libwebsocket_rx_flow_control(wsi, 1);
+ */
+
+ // libwebsocket_rx_flow_control(wsi,msgqueue.size() > 0);
+
+ libwebsocket_callback_on_writable(context, wsi);
+ usleep(200);
+ }
+ }
+ break;
+
+ case LWS_CALLBACK_BROADCAST:
+ printf("LWS_CALLBACK_BROADCAST\n");
+ n = libwebsocket_write(wsi, (unsigned char*)in, len, LWS_WRITE_TEXT);
+ if (n < 0) fprintf(stderr, "task write failed\n");
+ break;
+
+ case LWS_CALLBACK_RECEIVE:
+ {
+ printf("LWS_CALLBACK_RECEIVE\n");
+
+ printf("%s\n", (char*)in);
+ std::string data;
+ data.append((char*)in, len);
+
+ /*
+ struct a_message &msg = ringbuffer[ringbuffer_head];
+ if(msg.payload) {
+ free(msg.payload);
+ msg.payload = NULL;
+ }
+
+ */
+ char buf[1024];
+ size_t buf_len = 0;
+
+ std::string cmd = data.substr(0, data.find(' '));
+ printf("Cmd: %s\n", cmd.c_str());
+
+ if(cmd == "add") {
+ printf("Handling add cmd:\n");
+ int offset = cmd.length() + 1;
+ std::string title = data.substr(offset, data.find(' ', offset) - offset);
+ offset += title.length() + 1;
+ std::string desc = data.substr(offset, data.find(' ', offset) - offset);
+ offset += desc.length() + 1;
+ std::string x_str = data.substr(offset, data.find(' ', offset) - offset);
+ int x = atoi(x_str.c_str());
+ offset += x_str.length() + 1;
+ std::string y_str = data.substr(offset, data.find(' ', offset) - offset);
+ int y = atoi(y_str.c_str());
+
+ struct task t;
+ t.x = x;
+ t.y = y;
+ t.title = title;
+ t.desc = desc;
+ t.id = id_count; id_count++;
+ tasklist.push_back(t);
+
+ buf_len = sprintf(buf, "add %d %s %s %d %d;",
+ t.id, t.title.c_str(), t.desc.c_str(),
+ t.x, t.y);
+
+ printf("Adding task: %s\n", buf);
+
+ } else if(cmd == "del") {
+ printf("Delete\n");
+ int offset = cmd.length() + 1;
+ std::string id_str = data.substr(offset, data.find(' ', offset) - offset);
+ int id = atoi(id_str.c_str());
+ printf("Deleting task with id %d\n", id);
+
+ bool id_found = false;
+ TaskList::iterator it;
+ for(it = tasklist.begin(); it != tasklist.end(); it++) {
+ struct task t = *it;
+ if(t.id == id) {
+ id_found = true;
+ tasklist.erase(it);
+ break;
+ }
+ }
+
+ if(!id_found) {
+ printf("\t!!!Could not locate task with id %d\n", id);
+ }
+
+ buf_len = sprintf(buf, "del %d;", id);
+ printf("Deleting task: %s\n", buf);
+
+ } else if(cmd == "move") {
+ printf("Move\n");
+
+ int offset = cmd.length() + 1;
+ std::string s_id = data.substr(offset, data.find(' ', offset) - offset);
+ int id = atoi(s_id.c_str());
+ offset += s_id.length() + 1;
+ std::string x_str = data.substr(offset, data.find(' ', offset) - offset);
+ int x = atoi(x_str.c_str());
+ offset += x_str.length() + 1;
+ std::string y_str = data.substr(offset, data.find(' ', offset) - offset);
+ int y = atoi(y_str.c_str());
+
+ printf("Moving task with id %d to (%d,%d)\n", id, x, y);
+
+ bool id_found = false;
+ TaskList::iterator it;
+ for(it = tasklist.begin(); it != tasklist.end(); it++) {
+ struct task t = *it;
+ if(t.id == id) {
+ id_found = true;
+ t.x = x;
+ t.y = y;
+ break;
+ }
+ }
+
+ if(!id_found) {
+ printf("\t!!!Could not locate task with id %d\n", id);
+ }
+
+ buf_len = sprintf(buf, "move %d %d %d;", id, x / 300 * 300, y);
+ printf("Moving task: %s\n", buf);
+ } else if(cmd == "update") {
+ printf("Update\n");
+ }
+ else { // unknown command
+ printf("Unknown command :(\n");
+ break;
+ }
+
+// msg.payload = malloc(LWS_SEND_BUFFER_PRE_PADDING + len + LWS_SEND_BUFFER_POST_PADDING);
+// msg.len = len;
+// memcpy((char *)msg.payload + LWS_SEND_BUFFER_PRE_PADDING, in, len);
+// if(ringbuffer_head == (MAX_MESSAGE_QUEUE - 1)) ringbuffer_head = 0;
+// else ringbuffer_head++;
+/*
+ msg.payload = malloc(LWS_SEND_BUFFER_PRE_PADDING + buf_len
+ + LWS_SEND_BUFFER_POST_PADDING);
+ msg.len = buf_len;
+ memcpy((char *)msg.payload + LWS_SEND_BUFFER_PRE_PADDING,
+ buf, buf_len);
+ if(ringbuffer_head == (MAX_MESSAGE_QUEUE - 1)) ringbuffer_head = 0;
+ else ringbuffer_head++;
+*/
+ std::string msg;
+ msg.append((size_t)LWS_SEND_BUFFER_PRE_PADDING, ' ');
+ msg.append(buf, buf_len);
+ msg.append((size_t)LWS_SEND_BUFFER_POST_PADDING, ' ');
+ msgqueue.push(msg);
+ /*
+ if(((ringbuffer_head - pss->ringbuffer_tail) % MAX_MESSAGE_QUEUE) > (MAX_MESSAGE_QUEUE - 10))
+ libwebsocket_rx_flow_control(wsi, 0);
+ */
+ libwebsocket_callback_on_writable_all_protocol(libwebsockets_get_protocol(wsi));
+ //libwebsocket_rx_flow_control(wsi, 0);
+ }
+ break;
+ /*
+ * this just demonstrates how to use the protocol filter. If you won't
+ * study and reject connections based on header content, you don't need
+ * to handle this callback
+ */
+
+ case LWS_CALLBACK_FILTER_PROTOCOL_CONNECTION:
+ printf("LWS_CALLBACK_FILTER_PROTOCOL_CONNECTION\n");
+ dump_handshake_info((struct lws_tokens *)(long)user);
+ /* you could return non-zero here and kill the connection */
+ break;
+
+ default:
+ break;
+ }
+
+ return 0;
+}
diff --git a/src/task_proto.h b/src/task_proto.h
new file mode 100644
index 0000000..fe57752
--- /dev/null
+++ b/src/task_proto.h
@@ -0,0 +1,44 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set et sw=2 ts=2: */
+/***************************************************************************
+ * task_proto.h
+ *
+ * Fri Feb 24 08:23:15 CET 2012
+ * Copyright 2012 Bent Bisballe Nyeng
+ * deva@aasimon.org
+ ****************************************************************************/
+
+/*
+ * This file is part of Munia.
+ *
+ * Munia is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Munia is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Munia; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+#ifndef __MUNIA_TASK_PROTO_H__
+#define __MUNIA_TASK_PROTO_H__
+
+#include <stdlib.h>
+
+#include <libwebsockets.h>
+
+int callback_lws_task(struct libwebsocket_context * context,
+ struct libwebsocket *wsi,
+ enum libwebsocket_callback_reasons reason,
+ void *user, void *in, size_t len);
+
+struct per_session_data__lws_task {
+ struct libwebsocket *wsi;
+};
+
+#endif/*__MUNIA_TASK_PROTO_H__*/