1 /*
2  * Copyright (c) 2017-2021 Joris Vink <joris@coders.se>
3  *
4  * Permission to use, copy, modify, and distribute this software for any
5  * purpose with or without fee is hereby granted, provided that the above
6  * copyright notice and this permission notice appear in all copies.
7  *
8  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15  */
16 
17 #include <sys/param.h>
18 #include <sys/types.h>
19 
20 #include "kore.h"
21 
22 #if !defined(KORE_NO_HTTP)
23 #include "http.h"
24 #endif
25 
26 #if defined(KORE_USE_PYTHON)
27 #include "python_api.h"
28 #endif
29 
30 static void	native_runtime_execute(void *);
31 static int	native_runtime_onload(void *, int);
32 static void	native_runtime_connect(void *, struct connection *);
33 static void	native_runtime_configure(void *, int, char **);
34 #if !defined(KORE_NO_HTTP)
35 static int	native_runtime_http_request(void *, struct http_request *);
36 static int	native_runtime_validator(void *, struct http_request *,
37 		    const void *);
38 
39 static void	native_runtime_wsmessage(void *, struct connection *, u_int8_t,
40 		    const void *, size_t);
41 #endif
42 
43 struct kore_runtime kore_native_runtime = {
44 	KORE_RUNTIME_NATIVE,
45 #if !defined(KORE_NO_HTTP)
46 	.http_request = native_runtime_http_request,
47 	.validator = native_runtime_validator,
48 	.wsconnect = native_runtime_connect,
49 	.wsmessage = native_runtime_wsmessage,
50 	.wsdisconnect = native_runtime_connect,
51 #endif
52 	.onload = native_runtime_onload,
53 	.connect = native_runtime_connect,
54 	.execute = native_runtime_execute,
55 	.configure = native_runtime_configure
56 };
57 
58 struct kore_runtime_call *
kore_runtime_getcall(const char * symbol)59 kore_runtime_getcall(const char *symbol)
60 {
61 	void				*ptr;
62 	struct kore_runtime_call	*rcall;
63 	struct kore_runtime		*runtime;
64 
65 	ptr = kore_module_getsym(symbol, &runtime);
66 	if (ptr == NULL)
67 		return (NULL);
68 
69 	rcall = kore_malloc(sizeof(*rcall));
70 	rcall->addr = ptr;
71 	rcall->runtime = runtime;
72 
73 	return (rcall);
74 }
75 
76 void
kore_runtime_execute(struct kore_runtime_call * rcall)77 kore_runtime_execute(struct kore_runtime_call *rcall)
78 {
79 	rcall->runtime->execute(rcall->addr);
80 }
81 
82 void
kore_runtime_configure(struct kore_runtime_call * rcall,int argc,char ** argv)83 kore_runtime_configure(struct kore_runtime_call *rcall, int argc, char **argv)
84 {
85 	rcall->runtime->configure(rcall->addr, argc, argv);
86 }
87 
88 int
kore_runtime_onload(struct kore_runtime_call * rcall,int action)89 kore_runtime_onload(struct kore_runtime_call *rcall, int action)
90 {
91 	return (rcall->runtime->onload(rcall->addr, action));
92 }
93 
94 void
kore_runtime_connect(struct kore_runtime_call * rcall,struct connection * c)95 kore_runtime_connect(struct kore_runtime_call *rcall, struct connection *c)
96 {
97 	rcall->runtime->connect(rcall->addr, c);
98 }
99 
100 #if !defined(KORE_NO_HTTP)
101 int
kore_runtime_http_request(struct kore_runtime_call * rcall,struct http_request * req)102 kore_runtime_http_request(struct kore_runtime_call *rcall,
103     struct http_request *req)
104 {
105 	return (rcall->runtime->http_request(rcall->addr, req));
106 }
107 
108 int
kore_runtime_validator(struct kore_runtime_call * rcall,struct http_request * req,const void * data)109 kore_runtime_validator(struct kore_runtime_call *rcall,
110     struct http_request *req, const void *data)
111 {
112 	return (rcall->runtime->validator(rcall->addr, req, data));
113 }
114 
115 void
kore_runtime_wsconnect(struct kore_runtime_call * rcall,struct connection * c)116 kore_runtime_wsconnect(struct kore_runtime_call *rcall, struct connection *c)
117 {
118 	rcall->runtime->wsconnect(rcall->addr, c);
119 }
120 
121 void
kore_runtime_wsmessage(struct kore_runtime_call * rcall,struct connection * c,u_int8_t op,const void * data,size_t len)122 kore_runtime_wsmessage(struct kore_runtime_call *rcall, struct connection *c,
123     u_int8_t op, const void *data, size_t len)
124 {
125 	rcall->runtime->wsmessage(rcall->addr, c, op, data, len);
126 }
127 
128 void
kore_runtime_wsdisconnect(struct kore_runtime_call * rcall,struct connection * c)129 kore_runtime_wsdisconnect(struct kore_runtime_call *rcall, struct connection *c)
130 {
131 	rcall->runtime->wsdisconnect(rcall->addr, c);
132 }
133 #endif
134 
135 static void
native_runtime_execute(void * addr)136 native_runtime_execute(void *addr)
137 {
138 	void	(*cb)(void);
139 
140 	*(void **)&(cb) = addr;
141 	cb();
142 }
143 
144 static void
native_runtime_configure(void * addr,int argc,char ** argv)145 native_runtime_configure(void *addr, int argc, char **argv)
146 {
147 	void	(*cb)(int, char **);
148 
149 	*(void **)&(cb) = addr;
150 	cb(argc, argv);
151 }
152 
153 static void
native_runtime_connect(void * addr,struct connection * c)154 native_runtime_connect(void *addr, struct connection *c)
155 {
156 	void	(*cb)(struct connection *);
157 
158 	*(void **)&(cb) = addr;
159 	cb(c);
160 }
161 
162 static int
native_runtime_onload(void * addr,int action)163 native_runtime_onload(void *addr, int action)
164 {
165 	int		(*cb)(int);
166 
167 	*(void **)&(cb) = addr;
168 	return (cb(action));
169 }
170 
171 #if !defined(KORE_NO_HTTP)
172 static int
native_runtime_http_request(void * addr,struct http_request * req)173 native_runtime_http_request(void *addr, struct http_request *req)
174 {
175 	int		(*cb)(struct http_request *);
176 
177 	*(void **)&(cb) = addr;
178 	return (cb(req));
179 }
180 
181 static int
native_runtime_validator(void * addr,struct http_request * req,const void * data)182 native_runtime_validator(void *addr, struct http_request *req, const void *data)
183 {
184 	int		(*cb)(struct http_request *, const void *);
185 
186 	*(void **)&(cb) = addr;
187 	return (cb(req, data));
188 }
189 
190 static void
native_runtime_wsmessage(void * addr,struct connection * c,u_int8_t op,const void * data,size_t len)191 native_runtime_wsmessage(void *addr, struct connection *c, u_int8_t op,
192     const void *data, size_t len)
193 {
194 	void	(*cb)(struct connection *, u_int8_t, const void *, size_t);
195 
196 	*(void **)&(cb) = addr;
197 	cb(c, op, data, len);
198 
199 }
200 #endif
201