1/* 2 * ws protocol handler plugin for "dumb increment" 3 * 4 * Written in 2010-2019 by Andy Green <andy@warmcat.com> 5 * 6 * This file is made available under the Creative Commons CC0 1.0 7 * Universal Public Domain Dedication. 8 * 9 * The person who associated a work with this deed has dedicated 10 * the work to the public domain by waiving all of his or her rights 11 * to the work worldwide under copyright law, including all related 12 * and neighboring rights, to the extent allowed by law. You can copy, 13 * modify, distribute and perform the work, even for commercial purposes, 14 * all without asking permission. 15 * 16 * These test plugins are intended to be adapted for use in your code, which 17 * may be proprietary. So unlike the library itself, they are licensed 18 * Public Domain. 19 * 20 * This is a copy of dumb_increment adapted slightly to serve as the 21 * "example-standalone-protocol", to show how to build protocol plugins 22 * outside the library easily. 23 */ 24 25#if !defined (LWS_PLUGIN_STATIC) 26#if !defined(LWS_DLL) 27#define LWS_DLL 28#endif 29#if !defined(LWS_INTERNAL) 30#define LWS_INTERNAL 31#endif 32#include <libwebsockets.h> 33#endif 34 35#include <string.h> 36 37struct per_vhost_data__dumb_increment { 38 uv_timer_t timeout_watcher; 39 struct lws_context *context; 40 struct lws_vhost *vhost; 41 const struct lws_protocols *protocol; 42}; 43 44struct per_session_data__dumb_increment { 45 int number; 46}; 47 48static void 49uv_timeout_cb_dumb_increment(uv_timer_t *w 50#if UV_VERSION_MAJOR == 0 51 , int status 52#endif 53) 54{ 55 struct per_vhost_data__dumb_increment *vhd = lws_container_of(w, 56 struct per_vhost_data__dumb_increment, timeout_watcher); 57 lws_callback_on_writable_all_protocol_vhost(vhd->vhost, vhd->protocol); 58} 59 60static int 61callback_dumb_increment(struct lws *wsi, enum lws_callback_reasons reason, 62 void *user, void *in, size_t len) 63{ 64 struct per_session_data__dumb_increment *pss = 65 (struct per_session_data__dumb_increment *)user; 66 struct per_vhost_data__dumb_increment *vhd = 67 (struct per_vhost_data__dumb_increment *) 68 lws_protocol_vh_priv_get(lws_get_vhost(wsi), 69 lws_get_protocol(wsi)); 70 unsigned char buf[LWS_PRE + 512]; 71 unsigned char *p = &buf[LWS_PRE]; 72 int n, m; 73 74 switch (reason) { 75 case LWS_CALLBACK_PROTOCOL_INIT: 76 vhd = lws_protocol_vh_priv_zalloc(lws_get_vhost(wsi), 77 lws_get_protocol(wsi), 78 sizeof(struct per_vhost_data__dumb_increment)); 79 vhd->context = lws_get_context(wsi); 80 vhd->protocol = lws_get_protocol(wsi); 81 vhd->vhost = lws_get_vhost(wsi); 82 uv_timer_init(lws_uv_getloop(vhd->context, 0), 83 &vhd->timeout_watcher); 84 uv_timer_start(&vhd->timeout_watcher, 85 uv_timeout_cb_dumb_increment, 50, 50); 86 break; 87 88 case LWS_CALLBACK_PROTOCOL_DESTROY: 89 if (!vhd) 90 break; 91 uv_timer_stop(&vhd->timeout_watcher); 92 break; 93 94 case LWS_CALLBACK_ESTABLISHED: 95 pss->number = 0; 96 break; 97 98 case LWS_CALLBACK_SERVER_WRITEABLE: 99 n = sprintf((char *)p, "%d", pss->number++); 100 m = lws_write(wsi, p, n, LWS_WRITE_TEXT); 101 if (m < n) { 102 lwsl_err("ERROR %d writing to di socket\n", n); 103 return -1; 104 } 105 break; 106 107 case LWS_CALLBACK_RECEIVE: 108 if (len < 6) 109 break; 110 if (strcmp((const char *)in, "reset\n") == 0) 111 pss->number = 0; 112 if (strcmp((const char *)in, "closeme\n") == 0) { 113 lwsl_notice("dumb_inc: closing as requested\n"); 114 lws_close_reason(wsi, LWS_CLOSE_STATUS_GOINGAWAY, 115 (unsigned char *)"seeya", 5); 116 return -1; 117 } 118 break; 119 120 default: 121 break; 122 } 123 124 return 0; 125} 126 127static const struct lws_protocols protocols[] = { 128 { 129 "example-standalone-protocol", 130 callback_dumb_increment, 131 sizeof(struct per_session_data__dumb_increment), 132 10, /* rx buf size must be >= permessage-deflate rx size */ 133 }, 134}; 135 136LWS_VISIBLE const lws_plugin_protocol_t protocol_example_standalone = { 137 .hdr = { 138 "standalone", 139 "lws_protocol_plugin", 140 LWS_BUILD_HASH, 141 LWS_PLUGIN_API_MAGIC 142 }, 143 144 .protocols = protocols, 145 .count_protocols = LWS_ARRAY_SIZE(protocols), 146 .extensions = NULL, 147 .count_extensions = 0, 148}; 149