• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * lws-minimal-raw-file
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  * This demonstrates adopting a file descriptor into the lws event
10  * loop.
11  */
12 
13 #include <libwebsockets.h>
14 #include <string.h>
15 #include <signal.h>
16 #include <sys/types.h>
17 #include <sys/stat.h>
18 #include <fcntl.h>
19 
20 struct raw_vhd {
21 //	lws_sock_file_fd_type u;
22 	int filefd;
23 };
24 
25 static char filepath[256];
26 
27 static int
callback_raw_test(struct lws * wsi,enum lws_callback_reasons reason,void * user,void * in,size_t len)28 callback_raw_test(struct lws *wsi, enum lws_callback_reasons reason,
29 			void *user, void *in, size_t len)
30 {
31 	struct raw_vhd *vhd = (struct raw_vhd *)lws_protocol_vh_priv_get(
32 				     lws_get_vhost(wsi), lws_get_protocol(wsi));
33 	lws_sock_file_fd_type u;
34 	uint8_t buf[1024];
35 	int n;
36 
37 	switch (reason) {
38 	case LWS_CALLBACK_PROTOCOL_INIT:
39 		vhd = lws_protocol_vh_priv_zalloc(lws_get_vhost(wsi),
40 				lws_get_protocol(wsi), sizeof(struct raw_vhd));
41 		vhd->filefd = lws_open(filepath, O_RDWR);
42 		if (vhd->filefd == -1) {
43 			lwsl_err("Unable to open %s\n", filepath);
44 
45 			return 1;
46 		}
47 		u.filefd = (lws_filefd_type)(long long)vhd->filefd;
48 		if (!lws_adopt_descriptor_vhost(lws_get_vhost(wsi),
49 						LWS_ADOPT_RAW_FILE_DESC, u,
50 						"raw-test", NULL)) {
51 			lwsl_err("Failed to adopt fifo descriptor\n");
52 			close(vhd->filefd);
53 			vhd->filefd = -1;
54 
55 			return 1;
56 		}
57 		break;
58 
59 	case LWS_CALLBACK_PROTOCOL_DESTROY:
60 		if (vhd && vhd->filefd != -1)
61 			close(vhd->filefd);
62 		break;
63 
64 	/* callbacks related to raw file descriptor */
65 
66 	case LWS_CALLBACK_RAW_ADOPT_FILE:
67 		lwsl_notice("LWS_CALLBACK_RAW_ADOPT_FILE\n");
68 		break;
69 
70 	case LWS_CALLBACK_RAW_RX_FILE:
71 		lwsl_notice("LWS_CALLBACK_RAW_RX_FILE\n");
72 		n = (int)read(vhd->filefd, buf, sizeof(buf));
73 		if (n < 0) {
74 			lwsl_err("Reading from %s failed\n", filepath);
75 
76 			return 1;
77 		}
78 		lwsl_hexdump_level(LLL_NOTICE, buf, (unsigned int)n);
79 		break;
80 
81 	case LWS_CALLBACK_RAW_CLOSE_FILE:
82 		lwsl_notice("LWS_CALLBACK_RAW_CLOSE_FILE\n");
83 		break;
84 
85 	case LWS_CALLBACK_RAW_WRITEABLE_FILE:
86 		lwsl_notice("LWS_CALLBACK_RAW_WRITEABLE_FILE\n");
87 		/*
88 		 * you can call lws_callback_on_writable() on a raw file wsi as
89 		 * usual, and then write directly into the raw filefd here.
90 		 */
91 		break;
92 
93 	default:
94 		break;
95 	}
96 
97 	return 0;
98 }
99 
100 static struct lws_protocols protocols[] = {
101 	{ "raw-test", callback_raw_test, 0, 0, 0, NULL, 0 },
102 	LWS_PROTOCOL_LIST_TERM
103 };
104 
105 static int interrupted;
106 
sigint_handler(int sig)107 void sigint_handler(int sig)
108 {
109 	interrupted = 1;
110 }
111 
main(int argc,const char ** argv)112 int main(int argc, const char **argv)
113 {
114 	struct lws_context_creation_info info;
115 	struct lws_context *context;
116 	const char *p;
117 	int n = 0, logs = LLL_USER | LLL_ERR | LLL_WARN | LLL_NOTICE
118 			/* for LLL_ verbosity above NOTICE to be built into lws,
119 			 * lws must have been configured and built with
120 			 * -DCMAKE_BUILD_TYPE=DEBUG instead of =RELEASE */
121 			/* | LLL_INFO */ /* | LLL_PARSER */ /* | LLL_HEADER */
122 			/* | LLL_EXT */ /* | LLL_CLIENT */ /* | LLL_LATENCY */
123 			/* | LLL_DEBUG */;
124 
125 	signal(SIGINT, sigint_handler);
126 
127 	if ((p = lws_cmdline_option(argc, argv, "-d")))
128 		logs = atoi(p);
129 
130 	lws_set_log_level(logs, NULL);
131 	lwsl_user("LWS minimal raw file\n");
132 	if (argc < 2) {
133 		lwsl_user("Usage: %s <file to monitor>  "
134 			  " eg, /dev/ttyUSB0 or /dev/input/event0 or "
135 			  "/proc/self/fd/0\n", argv[0]);
136 
137 		return 1;
138 	}
139 
140 	signal(SIGINT, sigint_handler);
141 
142 	memset(&info, 0, sizeof info); /* otherwise uninitialized garbage */
143 	info.port = CONTEXT_PORT_NO_LISTEN_SERVER; /* no listen socket for demo */
144 	info.protocols = protocols;
145 
146 	lws_strncpy(filepath, argv[1], sizeof(filepath));
147 
148 	context = lws_create_context(&info);
149 	if (!context) {
150 		lwsl_err("lws init failed\n");
151 		return 1;
152 	}
153 
154 	while (n >= 0 && !interrupted)
155 		n = lws_service(context, 0);
156 
157 	lws_context_destroy(context);
158 
159 	return 0;
160 }
161