From f544faf78d57488b951b8ac2c52cc5b0127e16eb Mon Sep 17 00:00:00 2001 From: Joshua Moerman Date: Thu, 28 Feb 2013 14:59:04 +0100 Subject: [PATCH] initial commit --- .gitmodules | 3 + OnlineBeats.sublime-project | 17 +++ contrib/libwebsockets | 1 + main.cpp | 244 ++++++++++++++++++++++++++++++++++++ 4 files changed, 265 insertions(+) create mode 100644 .gitmodules create mode 100644 OnlineBeats.sublime-project create mode 160000 contrib/libwebsockets create mode 100644 main.cpp diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..a4e2a7c --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "contrib/libwebsockets"] + path = contrib/libwebsockets + url = git://github.com/warmcat/libwebsockets.git diff --git a/OnlineBeats.sublime-project b/OnlineBeats.sublime-project new file mode 100644 index 0000000..300d5b5 --- /dev/null +++ b/OnlineBeats.sublime-project @@ -0,0 +1,17 @@ +{ + "folders": + [ + { + "path": "/Users/joshua/Documents/Code/OnlineBeats" + } + ], + + "settings": + { + "sublimeclang_options": + [ + "-isystem${folder:${project_path:OnlineBeats.sublime-project}}/contrib/libwebsockets/", + "-Wall" + ] + } +} diff --git a/contrib/libwebsockets b/contrib/libwebsockets new file mode 160000 index 0000000..1bc12f9 --- /dev/null +++ b/contrib/libwebsockets @@ -0,0 +1 @@ +Subproject commit 1bc12f9e992851a773166936317d54ea7242feb1 diff --git a/main.cpp b/main.cpp new file mode 100644 index 0000000..6115fd4 --- /dev/null +++ b/main.cpp @@ -0,0 +1,244 @@ +/* + * libwebsockets-test-echo - libwebsockets echo test implementation + * + * This implements both the client and server sides. It defaults to + * serving, use --client to connect as client. + * + * Copyright (C) 2010-2013 Andy Green + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation: + * version 2.1 of the License. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef CMAKE_BUILD +#include "lws_config.h" +#endif + +#include "lib/libwebsockets.h" + +int force_exit = 0; + +#define MAX_ECHO_PAYLOAD 1400 + +struct per_session_data__echo { + unsigned char buf[LWS_SEND_BUFFER_PRE_PADDING + MAX_ECHO_PAYLOAD + LWS_SEND_BUFFER_POST_PADDING]; + unsigned int len; + unsigned int index; +}; + +static int +callback_echo(struct libwebsocket_context *context, + struct libwebsocket *wsi, + enum libwebsocket_callback_reasons reason, void *user, + void *in, size_t len){ + struct per_session_data__echo *pss = (struct per_session_data__echo *)user; + int n; + + switch (reason) { + case LWS_CALLBACK_SERVER_WRITEABLE: + n = libwebsocket_write(wsi, &pss->buf[LWS_SEND_BUFFER_PRE_PADDING], pss->len, LWS_WRITE_TEXT); + if (n < 0) { + lwsl_err("ERROR %d writing to socket, hanging up\n", n); + return 1; + } + if (n < pss->len) { + lwsl_err("Partial write\n"); + return -1; + } + break; + + case LWS_CALLBACK_RECEIVE: + if (len > MAX_ECHO_PAYLOAD) { + lwsl_err("Server received packet bigger than %u, hanging up\n", MAX_ECHO_PAYLOAD); + return 1; + } + memcpy(&pss->buf[LWS_SEND_BUFFER_PRE_PADDING], in, len); + pss->len = len; + libwebsocket_callback_on_writable(context, wsi); + break; + case LWS_CALLBACK_CLIENT_ESTABLISHED: + case LWS_CALLBACK_CLIENT_RECEIVE: + case LWS_CALLBACK_CLIENT_WRITEABLE: + default: + break; + } + + return 0; +} + +static struct libwebsocket_protocols protocols[] = { + /* first protocol must always be HTTP handler */ + + { + "default", /* name */ + callback_echo, /* callback */ + sizeof(struct per_session_data__echo) /* per_session_data_size */ + }, + { + NULL, NULL, 0 /* End of list */ + } +}; + +void sighandler(int sig) +{ + force_exit = 1; +} + +static struct option options[] = { + { "help", no_argument, NULL, 'h' }, + { "debug", required_argument, NULL, 'd' }, + { "port", required_argument, NULL, 'p' }, + { "ssl", no_argument, NULL, 's' }, + { "interface", required_argument, NULL, 'i' }, +#ifndef LWS_NO_DAEMONIZE + { "daemonize", no_argument, NULL, 'D' }, +#endif + { NULL, 0, 0, 0 } +}; + +int main(int argc, char **argv){ + int n = 0; + int port = 7681; + int use_ssl = 0; + struct libwebsocket_context *context; + int opts = 0; + char interface_name[128] = ""; + const char *interface = NULL; + int syslog_options = LOG_PID | LOG_PERROR; + int client = 0; + int listen_port; + struct lws_context_creation_info info; + + int debug_level = 7; +#ifndef LWS_NO_DAEMONIZE + int daemonize = 0; +#endif + + memset(&info, 0, sizeof info); + +#ifndef LWS_NO_SERVER + lwsl_notice("Built to support server operations\n"); +#endif + + while (n >= 0) { + n = getopt_long(argc, argv, "i:hsp:d:D" + , options, NULL); + if (n < 0) + continue; + switch (n) { +#ifndef LWS_NO_DAEMONIZE + case 'D': + daemonize = 1; + syslog_options &= ~LOG_PERROR; + break; +#endif + case 'd': + debug_level = atoi(optarg); + break; + case 's': + use_ssl = 1; /* 1 = take care about cert verification, 2 = allow anything */ + break; + case 'p': + port = atoi(optarg); + break; + case 'i': + strncpy(interface_name, optarg, sizeof interface_name); + interface_name[(sizeof interface_name) - 1] = '\0'; + interface = interface_name; + break; + case '?': + case 'h': + fprintf(stderr, "Usage: libwebsockets-test-echo " + "[--ssl] " + "[--port=

] " + "[-d ]\n"); + exit(1); + } + } + +#ifndef LWS_NO_DAEMONIZE + /* + * normally lock path would be /var/lock/lwsts or similar, to + * simplify getting started without having to take care about + * permissions or running as root, set to /tmp/.lwsts-lock + */ + if (!client && daemonize && lws_daemonize("/tmp/.lwstecho-lock")) { + fprintf(stderr, "Failed to daemonize\n"); + return 1; + } +#endif + + /* we will only try to log things according to our debug_level */ + setlogmask(LOG_UPTO (LOG_DEBUG)); + openlog("lwsts", syslog_options, LOG_DAEMON); + + /* tell the library what debug level to emit and to send it to syslog */ + lws_set_log_level(debug_level, lwsl_emit_syslog); + + lwsl_notice("libwebsockets echo test - " + "(C) Copyright 2010-2013 Andy Green - " + "licensed under LGPL2.1\n"); + +#ifndef LWS_NO_SERVER + lwsl_notice("Running in server mode\n"); + listen_port = port; +#endif + + info.port = listen_port; + info.iface = interface; + info.protocols = protocols; +#ifndef LWS_NO_EXTENSIONS + info.extensions = libwebsocket_get_internal_extensions(); +#endif + if (use_ssl && !client) { + info.ssl_cert_filepath = "libwebsockets-test-server.pem"; + info.ssl_private_key_filepath = "libwebsockets-test-server.key.pem"; + } + info.gid = -1; + info.uid = -1; + info.options = opts; + + context = libwebsocket_create_context(&info); + + if (context == NULL) { + lwsl_err("libwebsocket init failed\n"); + return -1; + } + + signal(SIGINT, sighandler); + + n = 0; + while (n >= 0 && !force_exit) { + n = libwebsocket_service(context, 10); + } + + libwebsocket_context_destroy(context); + + lwsl_notice("libwebsockets-test-echo exited cleanly\n"); + + closelog(); + + return 0; +}