diff options
author | Bent Bisballe Nyeng <deva@aasimon.org> | 2012-02-24 14:04:02 +0100 |
---|---|---|
committer | Bent Bisballe Nyeng <deva@aasimon.org> | 2012-02-24 14:04:02 +0100 |
commit | 227745a7445abbd3cff71825a5559656f495cb89 (patch) | |
tree | 2e42e6608ec2bd3cb3e35c057c7c17631b1326a2 | |
parent | 3ca0e592183839f339d47723ca51be1ca2bbc7ec (diff) |
In development...
-rw-r--r-- | munia.html | 6 | ||||
-rw-r--r-- | src/Makefile.am | 6 | ||||
-rw-r--r-- | src/muniad.cc | 430 | ||||
-rw-r--r-- | src/task_proto.cc | 347 | ||||
-rw-r--r-- | src/task_proto.h | 44 |
5 files changed, 414 insertions, 419 deletions
@@ -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__*/ |