Subject: windows: support to bind to a specific IPv6 address
[platform/upstream/libwebsockets.git] / lib / lws-plat-optee.c
1 #include "private-libwebsockets.h"
2
3 /*
4  * included from libwebsockets.c for OPTEE builds
5  */
6
7 void TEE_GenerateRandom(void *randomBuffer, uint32_t randomBufferLen);
8
9 unsigned long long time_in_microseconds(void)
10 {
11         return ((unsigned long long)time(NULL)) * 1000000;
12 }
13 #if 0
14 LWS_VISIBLE int
15 lws_get_random(struct lws_context *context, void *buf, int len)
16 {
17         TEE_GenerateRandom(buf, len);
18
19         return len;
20 }
21 #endif
22 LWS_VISIBLE int
23 lws_send_pipe_choked(struct lws *wsi)
24 {
25 #if 0
26         struct lws_pollfd fds;
27
28         /* treat the fact we got a truncated send pending as if we're choked */
29         if (wsi->trunc_len)
30                 return 1;
31
32         fds.fd = wsi->desc.sockfd;
33         fds.events = POLLOUT;
34         fds.revents = 0;
35
36         if (poll(&fds, 1, 0) != 1)
37                 return 1;
38
39         if ((fds.revents & POLLOUT) == 0)
40                 return 1;
41 #endif
42         /* okay to send another packet without blocking */
43
44         return 0;
45 }
46
47 LWS_VISIBLE int
48 lws_poll_listen_fd(struct lws_pollfd *fd)
49 {
50 //      return poll(fd, 1, 0);
51
52         return 0;
53 }
54
55 LWS_VISIBLE void
56 lws_cancel_service_pt(struct lws *wsi)
57 {
58 #if 0
59         struct lws_context_per_thread *pt = &wsi->context->pt[(int)wsi->tsi];
60         char buf = 0;
61
62         if (write(pt->dummy_pipe_fds[1], &buf, sizeof(buf)) != 1)
63                 lwsl_err("Cannot write to dummy pipe");
64 #endif
65 }
66
67 LWS_VISIBLE void
68 lws_cancel_service(struct lws_context *context)
69 {
70 #if 0
71         struct lws_context_per_thread *pt = &context->pt[0];
72         char buf = 0, m = context->count_threads;
73
74         while (m--) {
75                 if (write(pt->dummy_pipe_fds[1], &buf, sizeof(buf)) != 1)
76                         lwsl_err("Cannot write to dummy pipe");
77                 pt++;
78         }
79 #endif
80 }
81 #if 0
82 LWS_VISIBLE void lwsl_emit_syslog(int level, const char *line)
83 {
84         IMSG("%d: %s\n", level, line);
85 }
86 #endif
87
88 LWS_VISIBLE LWS_EXTERN int
89 _lws_plat_service_tsi(struct lws_context *context, int timeout_ms, int tsi)
90 {
91         struct lws_context_per_thread *pt;
92         int n = -1, m, c;
93         //char buf;
94
95         /* stay dead once we are dead */
96
97         if (!context || !context->vhost_list)
98                 return 1;
99
100         pt = &context->pt[tsi];
101
102         if (timeout_ms < 0)
103                 goto faked_service;
104
105         if (!context->service_tid_detected) {
106                 struct lws _lws;
107
108                 memset(&_lws, 0, sizeof(_lws));
109                 _lws.context = context;
110
111                 context->service_tid_detected =
112                         context->vhost_list->protocols[0].callback(
113                         &_lws, LWS_CALLBACK_GET_THREAD_ID, NULL, NULL, 0);
114         }
115         context->service_tid = context->service_tid_detected;
116
117         /*
118          * is there anybody with pending stuff that needs service forcing?
119          */
120         if (!lws_service_adjust_timeout(context, 1, tsi)) {
121                 lwsl_notice("%s: doing forced service\n", __func__);
122                 /* -1 timeout means just do forced service */
123                 _lws_plat_service_tsi(context, -1, pt->tid);
124                 /* still somebody left who wants forced service? */
125                 if (!lws_service_adjust_timeout(context, 1, pt->tid))
126                         /* yes... come back again quickly */
127                         timeout_ms = 0;
128         }
129 #if 1
130         n = poll(pt->fds, pt->fds_count, timeout_ms);
131
132 #ifdef LWS_OPENSSL_SUPPORT
133         if (!pt->rx_draining_ext_list &&
134             !lws_ssl_anybody_has_buffered_read_tsi(context, tsi) && !n) {
135 #else
136         if (!pt->rx_draining_ext_list && !n) /* poll timeout */ {
137 #endif
138                 lws_service_fd_tsi(context, NULL, tsi);
139                 return 0;
140         }
141 #endif
142 faked_service:
143         m = lws_service_flag_pending(context, tsi);
144         if (m)
145                 c = -1; /* unknown limit */
146         else
147                 if (n < 0) {
148                         if (LWS_ERRNO != LWS_EINTR)
149                                 return -1;
150                         return 0;
151                 } else
152                         c = n;
153
154         /* any socket with events to service? */
155         for (n = 0; n < pt->fds_count && c; n++) {
156                 if (!pt->fds[n].revents)
157                         continue;
158
159                 c--;
160 #if 0
161                 if (pt->fds[n].fd == pt->dummy_pipe_fds[0]) {
162                         if (read(pt->fds[n].fd, &buf, 1) != 1)
163                                 lwsl_err("Cannot read from dummy pipe.");
164                         continue;
165                 }
166 #endif
167                 m = lws_service_fd_tsi(context, &pt->fds[n], tsi);
168                 if (m < 0)
169                         return -1;
170                 /* if something closed, retry this slot */
171                 if (m)
172                         n--;
173         }
174
175         return 0;
176 }
177
178 LWS_VISIBLE int
179 lws_plat_check_connection_error(struct lws *wsi)
180 {
181         return 0;
182 }
183
184 LWS_VISIBLE int
185 lws_plat_service(struct lws_context *context, int timeout_ms)
186 {
187         return _lws_plat_service_tsi(context, timeout_ms, 0);
188 }
189
190 LWS_VISIBLE int
191 lws_plat_set_socket_options(struct lws_vhost *vhost, int fd)
192 {
193         return 0;
194 }
195
196 LWS_VISIBLE void
197 lws_plat_drop_app_privileges(struct lws_context_creation_info *info)
198 {
199 }
200
201 LWS_VISIBLE int
202 lws_plat_context_early_init(void)
203 {
204         return 0;
205 }
206
207 LWS_VISIBLE void
208 lws_plat_context_early_destroy(struct lws_context *context)
209 {
210 }
211
212 LWS_VISIBLE void
213 lws_plat_context_late_destroy(struct lws_context *context)
214 {
215         if (context->lws_lookup)
216                 lws_free(context->lws_lookup);
217 }
218
219 /* cast a struct sockaddr_in6 * into addr for ipv6 */
220
221 LWS_VISIBLE int
222 lws_interface_to_sa(int ipv6, const char *ifname, struct sockaddr_in *addr,
223                     size_t addrlen)
224 {
225         return -1;
226 }
227
228 LWS_VISIBLE void
229 lws_plat_insert_socket_into_fds(struct lws_context *context, struct lws *wsi)
230 {
231         struct lws_context_per_thread *pt = &context->pt[(int)wsi->tsi];
232
233         pt->fds[pt->fds_count++].revents = 0;
234 }
235
236 LWS_VISIBLE void
237 lws_plat_delete_socket_from_fds(struct lws_context *context,
238                                                 struct lws *wsi, int m)
239 {
240         struct lws_context_per_thread *pt = &context->pt[(int)wsi->tsi];
241
242         pt->fds_count--;
243 }
244
245 LWS_VISIBLE void
246 lws_plat_service_periodic(struct lws_context *context)
247 {
248 }
249
250 LWS_VISIBLE int
251 lws_plat_change_pollfd(struct lws_context *context,
252                       struct lws *wsi, struct lws_pollfd *pfd)
253 {
254         return 0;
255 }
256
257 LWS_VISIBLE const char *
258 lws_plat_inet_ntop(int af, const void *src, char *dst, int cnt)
259 {
260         //return inet_ntop(af, src, dst, cnt);
261         return "lws_plat_inet_ntop";
262 }
263
264 LWS_VISIBLE int
265 lws_plat_inet_pton(int af, const char *src, void *dst)
266 {
267         //return inet_pton(af, src, dst);
268         return 1;
269 }
270
271 LWS_VISIBLE lws_fop_fd_t
272 _lws_plat_file_open(lws_plat_file_open(struct lws_plat_file_ops *fops,
273                     const char *filename, lws_fop_flags_t *flags)
274 {
275         return NULL;
276 }
277
278 LWS_VISIBLE int
279 _lws_plat_file_close(lws_fop_fd_t *fop_fd)
280 {
281         return 0;
282 }
283
284 LWS_VISIBLE lws_fileofs_t
285 _lws_plat_file_seek_cur(lws_fop_fd_t fop_fd, lws_fileofs_t offset)
286 {
287         return 0;
288 }
289
290 LWS_VISIBLE  int
291 _lws_plat_file_read(lws_fop_fd_t fop_fd, lws_filepos_t *amount,
292                     uint8_t *buf, lws_filepos_t len)
293 {
294
295         return 0;
296 }
297
298 LWS_VISIBLE  int
299 _lws_plat_file_write(lws_fop_fd_t fop_fd, lws_filepos_t *amount,
300                      uint8_t *buf, lws_filepos_t len)
301 {
302
303         return 0;
304 }
305
306
307 LWS_VISIBLE int
308 lws_plat_init(struct lws_context *context,
309               struct lws_context_creation_info *info)
310 {
311         /* master context has the global fd lookup array */
312         context->lws_lookup = lws_zalloc(sizeof(struct lws *) *
313                                          context->max_fds);
314         if (context->lws_lookup == NULL) {
315                 lwsl_err("OOM on lws_lookup array for %d connections\n",
316                          context->max_fds);
317                 return 1;
318         }
319
320         lwsl_notice(" mem: platform fd map: %5lu bytes\n",
321                     (long)sizeof(struct lws *) * context->max_fds);
322
323 #ifdef LWS_WITH_PLUGINS
324         if (info->plugin_dirs)
325                 lws_plat_plugins_init(context, info->plugin_dirs);
326 #endif
327
328         return 0;
329 }