GCC Code Coverage Report


Directory: src/gate/
File: src/gate/interfaces/socop_impl.c
Date: 2025-09-14 13:10:38
Exec Total Coverage
Lines: 0 468 0.0%
Functions: 0 29 0.0%
Branches: 0 213 0.0%

Line Branch Exec Source
1 #include "socop.h"
2
3 #include <stdlib.h>
4 #include <string.h>
5
6 int socop_client_init(socop_client_t* session,
7 socop_read_byte_t reader_func, void* reader_param,
8 socop_write_byte_t writer_func, void* writer_param)
9 {
10 session->driver.read_byte = reader_func;
11 session->driver.read_param = reader_param;
12 session->driver.write_byte = writer_func;
13 session->driver.write_param = writer_param;
14 return SOCOP_ERROR_NOTIMPL;
15 }
16
17 static void serialize_word(unsigned char target[2], socop_word_t src)
18 {
19 target[0] = (unsigned char)(src >> 8);
20 target[1] = (unsigned char)(src & 0xff);
21 }
22
23 static void deserialize_word(socop_word_t* target, unsigned char const* src)
24 {
25 *target = ((((socop_word_t)src[0]) << 8) | ((socop_word_t)(src[1] & 0xff)));
26 }
27
28
29 int socop_driver_send_msg(socop_driver_t* driver, socop_msg_base_t const* msg, void const* data)
30 {
31 unsigned char msg_buffer[SOCOP_MSG_BASE_LENGTH];
32 unsigned ndx;
33 unsigned datalen = msg->msg_length - SOCOP_MSG_BASE_LENGTH;
34 unsigned char const* ptr_data = (unsigned char const*)data;
35 unsigned more; /* true until no more bytes will follow */
36 int result;
37
38 /* serialize header */
39 serialize_word(&msg_buffer[0], msg->msg_type);
40 serialize_word(&msg_buffer[2], msg->msg_length);
41 serialize_word(&msg_buffer[4], msg->resource_id);
42 serialize_word(&msg_buffer[6], msg->resource_param);
43 serialize_word(&msg_buffer[8], msg->state);
44 serialize_word(&msg_buffer[10], msg->user_param);
45
46 /* send header */
47 more = 1;
48 for (ndx = 0; ndx != SOCOP_MSG_BASE_LENGTH; ++ndx)
49 {
50 if (ndx == SOCOP_MSG_BASE_LENGTH - 1)
51 {
52 more = (datalen == 0) ? 0 : 1;
53 }
54 result = driver->write_byte(msg_buffer[ndx], more, driver->write_param);
55 if (result != SOCOP_OK)
56 {
57 return SOCOP_ERROR_IO;
58 }
59 }
60
61 /* send content if available */
62 for (ndx = 0; ndx != datalen; ++ndx)
63 {
64 more = (ndx == datalen - 1) ? 0 : 1;
65 result = driver->write_byte(ptr_data[ndx], more, driver->write_param);
66 if (result != SOCOP_OK)
67 {
68 return SOCOP_ERROR_IO;
69 }
70 }
71
72 return SOCOP_OK;
73 }
74
75 static int receive_buffer(socop_driver_t* driver, unsigned char* target, unsigned length)
76 {
77 unsigned ndx;
78 unsigned more;
79 int result;
80
81 for (ndx = 0; ndx != length; ++ndx)
82 {
83 more = (ndx == length - 1) ? 0 : 1;
84 result = driver->read_byte(&target[ndx], more, driver->read_param);
85 if (result == SOCOP_ERROR_TIMEOUT)
86 {
87 continue;
88 }
89 if (result != SOCOP_OK)
90 {
91 return result;
92 }
93 }
94 return SOCOP_OK;
95 }
96
97 int socop_driver_receive_msg(socop_driver_t* driver, socop_msg_buffer_t* buffer)
98 {
99 unsigned char msg_buffer[SOCOP_MSG_BASE_LENGTH];
100 unsigned data_len;
101 int result;
102
103 result = receive_buffer(driver, msg_buffer, SOCOP_MSG_BASE_LENGTH);
104 if (result != SOCOP_OK)
105 {
106 return result;
107 }
108
109 deserialize_word(&buffer->base.msg_type, &msg_buffer[0]);
110 deserialize_word(&buffer->base.msg_length, &msg_buffer[2]);
111 deserialize_word(&buffer->base.resource_id, &msg_buffer[4]);
112 deserialize_word(&buffer->base.resource_param, &msg_buffer[6]);
113 deserialize_word(&buffer->base.state, &msg_buffer[8]);
114 deserialize_word(&buffer->base.user_param, &msg_buffer[10]);
115
116 if (buffer->base.msg_length < SOCOP_MSG_BASE_LENGTH)
117 {
118 return SOCOP_ERROR_INVALIDDATA;
119 }
120 if ((buffer->base.msg_type & SOCOP_MSG_MASK) != SOCOP_MSG_MASK)
121 {
122 return SOCOP_ERROR_INVALIDDATA;
123 }
124
125 if (buffer->base.msg_length == SOCOP_MSG_BASE_LENGTH)
126 {
127 return SOCOP_OK;
128 }
129 data_len = buffer->base.msg_length - SOCOP_MSG_BASE_LENGTH;
130 if (data_len > sizeof(buffer->content))
131 {
132 return SOCOP_ERROR_OUTOFBOUNDS;
133 }
134 return receive_buffer(driver, (unsigned char*)&buffer->content[0], data_len);
135 }
136
137
138
139 static void init_msg_base(socop_msg_base_t* msg, socop_word_t type, socop_word_t sock_id, socop_word_t sock_param,
140 socop_word_t state, socop_word_t user, socop_word_t content_length)
141 {
142 msg->msg_type = type;
143 msg->msg_length = SOCOP_MSG_BASE_LENGTH + content_length;
144 msg->resource_id = sock_id;
145 msg->resource_param = sock_param;
146 msg->state = state;
147 msg->user_param = user;
148 }
149
150 static int receive_message_type(socop_driver_t* session, socop_msg_buffer_t* ptr_msg, socop_word_t desired_type, socop_word_t desired_resource_id)
151 {
152 int result = socop_driver_receive_msg(session, ptr_msg);
153 if (result != SOCOP_OK)
154 {
155 return result;
156 }
157 if (ptr_msg->base.msg_type != desired_type)
158 {
159 return SOCOP_ERROR_WRONGMESSAGE;
160 }
161 if (ptr_msg->base.state != SOCOP_OK)
162 {
163 return ptr_msg->base.state;
164 }
165 if (desired_resource_id && (ptr_msg->base.resource_id != desired_resource_id))
166 {
167 return SOCOP_ERROR_RESOURCEERROR;
168 }
169 return SOCOP_OK;
170 }
171
172 static socop_word_t serialize_addr(unsigned char target[6], socop_addr_t const* ptr_addr)
173 {
174 target[0] = ptr_addr->ip[0];
175 target[1] = ptr_addr->ip[1];
176 target[2] = ptr_addr->ip[2];
177 target[3] = ptr_addr->ip[3];
178 serialize_word(&target[4], ptr_addr->port);
179 return 6;
180 }
181
182 static void deserialize_addr(socop_addr_t* target, unsigned char const src[6])
183 {
184 target->ip[0] = src[0];
185 target->ip[1] = src[1];
186 target->ip[2] = src[2];
187 target->ip[3] = src[3];
188 deserialize_word(&target->port, &src[4]);
189 }
190
191
192 int socop_client_reset(socop_client_t* session)
193 {
194 int result;
195 socop_msg_buffer_t msg;
196
197 init_msg_base(&msg.base, SOCOP_MSG_RESET_REQUEST, 0, 0, 0, 0, 0);
198 result = socop_driver_send_msg(&session->driver, &msg.base, msg.content);
199 if (result != SOCOP_OK)
200 {
201 return result;
202 }
203 result = receive_message_type(&session->driver, &msg, SOCOP_MSG_RESET_RESPONSE, 0);
204 if (result != SOCOP_OK)
205 {
206 return result;
207 }
208 return SOCOP_OK;
209 }
210
211 int socop_client_netstatus(socop_client_t* session, void* ptr_status)
212 {
213 int result;
214 socop_msg_buffer_t msg;
215
216 init_msg_base(&msg.base, SOCOP_MSG_NET_STATUS_REQUEST, 0, 0, 0, 0, 0);
217 result = socop_driver_send_msg(&session->driver, &msg.base, msg.content);
218 if (result != SOCOP_OK)
219 {
220 return result;
221 }
222 result = receive_message_type(&session->driver, &msg, SOCOP_MSG_NET_STATUS_RESPONSE, 0);
223 if (result != SOCOP_OK)
224 {
225 return result;
226 }
227 return SOCOP_OK;
228 }
229
230 int socop_client_netstart(socop_client_t* session, char const* parameters, unsigned parameters_length)
231 {
232 int result;
233 socop_msg_buffer_t msg;
234 if (parameters_length > SOCOP_MAX_CONTENT_LENGTH)
235 {
236 parameters_length = SOCOP_MAX_CONTENT_LENGTH;
237 }
238
239 init_msg_base(&msg.base, SOCOP_MSG_NET_START_REQUEST, 0, 0, 0, 0, (socop_word_t)parameters_length);
240 result = socop_driver_send_msg(&session->driver, &msg.base, parameters);
241 if (result != SOCOP_OK)
242 {
243 return result;
244 }
245 result = receive_message_type(&session->driver, &msg, SOCOP_MSG_NET_START_RESPONSE, 0);
246 if (result != SOCOP_OK)
247 {
248 return result;
249 }
250 return SOCOP_OK;
251 }
252
253 int socop_client_netstop(socop_client_t* session)
254 {
255 int result;
256 socop_msg_buffer_t msg;
257
258 init_msg_base(&msg.base, SOCOP_MSG_NET_STOP_REQUEST, 0, 0, 0, 0, 0);
259 result = socop_driver_send_msg(&session->driver, &msg.base, NULL);
260 if (result != SOCOP_OK)
261 {
262 return result;
263 }
264 result = receive_message_type(&session->driver, &msg, SOCOP_MSG_NET_STOP_RESPONSE, 0);
265 if (result != SOCOP_OK)
266 {
267 return result;
268 }
269 return SOCOP_OK;
270 }
271
272 int socop_client_connect(socop_client_t* session, socop_addr_t const* addr, socop_socket_t* ptr_sock)
273 {
274 int result;
275 socop_msg_buffer_t msg;
276 const socop_word_t content_len = serialize_addr((unsigned char*)&msg.content[0], addr);
277
278 init_msg_base(&msg.base, SOCOP_MSG_SOCK_CONNECT_REQUEST, 0, 0, 0, 0, content_len);
279 result = socop_driver_send_msg(&session->driver, &msg.base, msg.content);
280 if (result != SOCOP_OK)
281 {
282 return result;
283 }
284 result = receive_message_type(&session->driver, &msg, SOCOP_MSG_SOCK_CONNECT_RESPONSE, 0);
285 if (result != SOCOP_OK)
286 {
287 return result;
288 }
289 if (msg.base.resource_id)
290 {
291 *ptr_sock = msg.base.resource_id;
292 return SOCOP_OK;
293 }
294 else
295 {
296 return SOCOP_ERROR_RESOURCEERROR;
297 }
298 }
299
300 int socop_client_bind(socop_client_t* session, socop_addr_t const* addr, socop_socket_t* ptr_sock)
301 {
302 int result;
303 socop_msg_buffer_t msg;
304 const socop_word_t content_len = serialize_addr((unsigned char*)&msg.content[0], addr);
305
306 init_msg_base(&msg.base, SOCOP_MSG_SOCK_BIND_REQUEST, 0, 0, 0, 0, content_len);
307 result = socop_driver_send_msg(&session->driver, &msg.base, msg.content);
308 if (result != SOCOP_OK)
309 {
310 return result;
311 }
312 result = receive_message_type(&session->driver, &msg, SOCOP_MSG_SOCK_BIND_RESPONSE, 0);
313 if (result != SOCOP_OK)
314 {
315 return result;
316 }
317 if (msg.base.resource_id)
318 {
319 *ptr_sock = msg.base.resource_id;
320 return SOCOP_OK;
321 }
322 else
323 {
324 return SOCOP_ERROR_RESOURCEERROR;
325 }
326 }
327
328 int socop_client_listen(socop_client_t* session, socop_addr_t const* addr, socop_socket_t* ptr_sock)
329 {
330 int result;
331 socop_msg_buffer_t msg;
332 const socop_word_t content_len = serialize_addr((unsigned char*)&msg.content[0], addr);
333
334 init_msg_base(&msg.base, SOCOP_MSG_SOCK_LISTEN_REQUEST, 0, 0, 0, 0, content_len);
335 result = socop_driver_send_msg(&session->driver, &msg.base, msg.content);
336 if (result != SOCOP_OK)
337 {
338 return result;
339 }
340 result = receive_message_type(&session->driver, &msg, SOCOP_MSG_SOCK_LISTEN_RESPONSE, 0);
341 if (result != SOCOP_OK)
342 {
343 return result;
344 }
345 if (msg.base.resource_id)
346 {
347 *ptr_sock = msg.base.resource_id;
348 return SOCOP_OK;
349 }
350 else
351 {
352 return SOCOP_ERROR_RESOURCEERROR;
353 }
354 }
355
356 int socop_client_accept(socop_client_t* session, socop_socket_t sock, socop_socket_t* ptr_sock)
357 {
358 int result;
359 socop_msg_buffer_t msg;
360
361 init_msg_base(&msg.base, SOCOP_MSG_SOCK_ACCEPT_REQUEST, sock, 0, 0, 0, 0);
362 result = socop_driver_send_msg(&session->driver, &msg.base, NULL);
363 if (result != SOCOP_OK)
364 {
365 return result;
366 }
367 result = receive_message_type(&session->driver, &msg, SOCOP_MSG_SOCK_ACCEPT_RESPONSE, 0);
368 if (result != SOCOP_OK)
369 {
370 return result;
371 }
372 /* original server socket is returned as resource_param */
373 if (msg.base.resource_param == sock)
374 {
375 *ptr_sock = msg.base.resource_id;
376 return SOCOP_OK;
377 }
378 else
379 {
380 return SOCOP_ERROR_RESOURCEERROR;
381 }
382 }
383
384
385 int socop_client_close(socop_client_t* session, socop_socket_t sock)
386 {
387 int result;
388 socop_msg_buffer_t msg;
389
390 init_msg_base(&msg.base, SOCOP_MSG_SOCK_CLOSE_REQUEST, sock, 0, 0, 0, 0);
391 result = socop_driver_send_msg(&session->driver, &msg.base, NULL);
392 if (result != SOCOP_OK)
393 {
394 return result;
395 }
396 return receive_message_type(&session->driver, &msg, SOCOP_MSG_SOCK_CLOSE_RESPONSE, 0);
397 }
398
399 int socop_client_receive(socop_client_t* session, socop_socket_t sock,
400 void* buffer, unsigned bufferlen, unsigned* bufferused)
401 {
402 int result;
403 socop_msg_buffer_t msg;
404 unsigned received_content;
405
406 if (bufferlen > SOCOP_MAX_CONTENT_LENGTH)
407 {
408 bufferlen = SOCOP_MAX_CONTENT_LENGTH;
409 }
410
411 init_msg_base(&msg.base, SOCOP_MSG_SOCK_RECV_REQUEST, sock, (socop_word_t)bufferlen, 0, 0, 0);
412 result = socop_driver_send_msg(&session->driver, &msg.base, NULL);
413 if (result != SOCOP_OK)
414 {
415 return result;
416 }
417 result = receive_message_type(&session->driver, &msg, SOCOP_MSG_SOCK_RECV_RESPONSE, sock);
418 if (result != SOCOP_OK)
419 {
420 return result;
421 }
422 received_content = msg.base.msg_length - SOCOP_MSG_BASE_LENGTH;
423 if (received_content)
424 {
425 memcpy(buffer, msg.content, received_content);
426 }
427 if (bufferused)
428 {
429 *bufferused = received_content;
430 }
431 return SOCOP_OK;
432 }
433
434 int socop_client_recv_from(socop_client_t* session, socop_socket_t sock,
435 void* buffer, unsigned bufferlen, unsigned* bufferused,
436 socop_addr_t* ptr_addr)
437 {
438 int result;
439 socop_msg_buffer_t msg;
440 unsigned address_length;
441 unsigned received_content;
442
443 if (bufferlen > (SOCOP_MAX_CONTENT_LENGTH - 8))
444 {
445 bufferlen = SOCOP_MAX_CONTENT_LENGTH - 8;
446 }
447
448 init_msg_base(&msg.base, SOCOP_MSG_SOCK_RECVFROM_REQUEST, sock, (socop_word_t)bufferlen, 0, 0, 0);
449 result = socop_driver_send_msg(&session->driver, &msg.base, NULL);
450 if (result != SOCOP_OK)
451 {
452 return result;
453 }
454 result = receive_message_type(&session->driver, &msg, SOCOP_MSG_SOCK_RECVFROM_RESPONSE, sock);
455 if (result != SOCOP_OK)
456 {
457 return result;
458 }
459
460 address_length = msg.base.resource_param;
461 if (address_length > (unsigned)(msg.base.msg_length - SOCOP_MSG_BASE_LENGTH))
462 {
463 return SOCOP_ERROR_CORRUPTION;
464 }
465
466 if (ptr_addr)
467 {
468 deserialize_addr(ptr_addr, (unsigned char const*)&msg.content[0]);
469 }
470
471 received_content = msg.base.msg_length - address_length - SOCOP_MSG_BASE_LENGTH;
472 if (received_content)
473 {
474 memcpy(buffer, &msg.content[address_length], received_content);
475 }
476 if (bufferused)
477 {
478 *bufferused = received_content;
479 }
480 return SOCOP_OK;
481 }
482
483 int socop_client_send(socop_client_t* session, socop_socket_t sock,
484 void const* buffer, unsigned bufferlen, unsigned* bufferused)
485 {
486 int result;
487 socop_msg_buffer_t msg;
488
489 if (bufferlen > (SOCOP_MAX_CONTENT_LENGTH))
490 {
491 bufferlen = SOCOP_MAX_CONTENT_LENGTH;
492 }
493
494 init_msg_base(&msg.base, SOCOP_MSG_SOCK_SEND_REQUEST, sock, 0, 0, 0, (socop_word_t)bufferlen);
495 result = socop_driver_send_msg(&session->driver, &msg.base, buffer);
496 if (result != SOCOP_OK)
497 {
498 return result;
499 }
500 result = receive_message_type(&session->driver, &msg, SOCOP_MSG_SOCK_SEND_RESPONSE, sock);
501 if (result != SOCOP_OK)
502 {
503 return result;
504 }
505 if (bufferused)
506 {
507 *bufferused = msg.base.resource_param;
508 }
509 return SOCOP_OK;
510 }
511
512 int socop_client_sendto(socop_client_t* session, socop_socket_t sock,
513 void const* buffer, unsigned bufferlen, unsigned* bufferused,
514 socop_addr_t const* ptr_addr)
515 {
516 int result;
517 socop_msg_buffer_t msg;
518 const socop_word_t addr_length = serialize_addr((unsigned char*)&msg.content[0], ptr_addr);
519
520 if (bufferlen > (unsigned)(SOCOP_MAX_CONTENT_LENGTH - addr_length))
521 {
522 bufferlen = SOCOP_MAX_CONTENT_LENGTH - addr_length;
523 }
524 memcpy(&msg.content[addr_length], buffer, bufferlen);
525
526 init_msg_base(&msg.base, SOCOP_MSG_SOCK_SENDTO_REQUEST, sock, addr_length, 0, 0, (socop_word_t)(bufferlen + addr_length));
527 result = socop_driver_send_msg(&session->driver, &msg.base, msg.content);
528 if (result != SOCOP_OK)
529 {
530 return result;
531 }
532 result = receive_message_type(&session->driver, &msg, SOCOP_MSG_SOCK_SENDTO_RESPONSE, sock);
533 if (result != SOCOP_OK)
534 {
535 return result;
536 }
537 if (bufferused)
538 {
539 *bufferused = msg.base.resource_param;
540 }
541 return SOCOP_OK;
542 }
543
544 int socop_client_shutdown(socop_client_t* session, socop_socket_t sock, unsigned target)
545 {
546 int result;
547 socop_msg_buffer_t msg;
548
549 init_msg_base(&msg.base, SOCOP_MSG_SOCK_SHUTDOWN_REQUEST, sock, (socop_word_t)target, 0, 0, 0);
550 result = socop_driver_send_msg(&session->driver, &msg.base, msg.content);
551 if (result != SOCOP_OK)
552 {
553 return result;
554 }
555 return receive_message_type(&session->driver, &msg, SOCOP_MSG_SOCK_SHUTDOWN_RESPONSE, sock);
556 }
557
558 int socop_client_select(socop_client_t* session, socop_socket_t sock, unsigned* flags, unsigned timeout_ms)
559 {
560 int result;
561 socop_msg_buffer_t msg;
562 const socop_word_t sel_flags = flags ? ((socop_word_t)*flags) : (SOCOP_MSG_FLAG_RECV | SOCOP_MSG_FLAG_SEND | SOCOP_MSG_FLAG_ERROR);
563 socop_word_t timeout;
564
565 if (timeout_ms > (unsigned int)0xffff)
566 {
567 timeout = 0xffff;
568 }
569 else
570 {
571 timeout = (socop_word_t)timeout_ms;
572 }
573
574 init_msg_base(&msg.base, SOCOP_MSG_SOCK_SELECT_REQUEST, sock, sel_flags, timeout, 0, 0);
575 result = socop_driver_send_msg(&session->driver, &msg.base, msg.content);
576 if (result != SOCOP_OK)
577 {
578 return result;
579 }
580 result = receive_message_type(&session->driver, &msg, SOCOP_MSG_SOCK_SELECT_RESPONSE, sock);
581 if (result != SOCOP_OK)
582 {
583 return result;
584 }
585 if (flags)
586 {
587 *flags = msg.base.resource_param;
588 }
589 return SOCOP_OK;
590 }
591
592 int socop_client_peer(socop_client_t* session, socop_socket_t sock, socop_addr_t* ptr_addr)
593 {
594 int result;
595 socop_msg_buffer_t msg;
596
597 init_msg_base(&msg.base, SOCOP_MSG_SOCK_PEER_REQUEST, sock, 0, 0, 0, 0);
598 result = socop_driver_send_msg(&session->driver, &msg.base, 0);
599 if (result != SOCOP_OK)
600 {
601 return result;
602 }
603 result = receive_message_type(&session->driver, &msg, SOCOP_MSG_SOCK_PEER_RESPONSE, sock);
604 if (result != SOCOP_OK)
605 {
606 return result;
607 }
608 deserialize_addr(ptr_addr, (unsigned char const*)&msg.content[0]);
609 return SOCOP_OK;
610 }
611
612 int socop_client_ioctl(socop_client_t* session, socop_socket_t sock, unsigned option, void* data, unsigned datalen)
613 {
614 int result;
615 socop_msg_buffer_t msg;
616 unsigned content_length;
617
618 if (datalen > SOCOP_MAX_CONTENT_LENGTH)
619 {
620 datalen = SOCOP_MAX_CONTENT_LENGTH;
621 }
622 if ((datalen > 0) && !data)
623 {
624 return SOCOP_ERROR_INVALIDARG;
625 }
626
627 init_msg_base(&msg.base, SOCOP_MSG_SOCK_IOCTL_REQUEST, sock, (socop_word_t)option, 0, 0, (socop_word_t)datalen);
628 result = socop_driver_send_msg(&session->driver, &msg.base, data);
629 if (result != SOCOP_OK)
630 {
631 return result;
632 }
633 result = receive_message_type(&session->driver, &msg, SOCOP_MSG_SOCK_IOCTL_RESPONSE, sock);
634 if (result != SOCOP_OK)
635 {
636 return result;
637 }
638 content_length = msg.base.msg_length - SOCOP_MSG_BASE_LENGTH;
639 if (content_length > datalen)
640 {
641 content_length = datalen;
642 }
643 if (content_length > 0)
644 {
645 memcpy(data, msg.content, content_length);
646 }
647 return SOCOP_OK;
648 }
649
650
651
652
653 int socop_server_init(socop_server_t* server, void* server_param,
654 socop_read_byte_t reader_func, void* reader_param, socop_write_byte_t writer_func, void* writer_param)
655 {
656 memset(server, 0, sizeof(socop_server_t));
657 server->server_param = server_param;
658 server->driver.read_byte = reader_func;
659 server->driver.read_param = reader_param;
660 server->driver.write_byte = writer_func;
661 server->driver.write_param = writer_param;
662 return SOCOP_OK;
663 }
664
665
666
667 int socop_server_chat_once(socop_server_t* server)
668 {
669 int result;
670 socop_msg_buffer_t msg = { 0 };
671 unsigned content_length = 0;
672 socop_addr_t addr = { 0 };
673 socop_socket_t sock = 0;
674 unsigned flags = 0;
675
676 result = socop_driver_receive_msg(&server->driver, &msg);
677 if (SOCOP_OK != result)
678 {
679 return result;
680 }
681
682 content_length = msg.base.msg_length - SOCOP_MSG_BASE_LENGTH;
683
684 switch (msg.base.msg_type)
685 {
686 case SOCOP_MSG_RESET_REQUEST:
687 {
688 if (!server->on_reset)
689 {
690 result = SOCOP_ERROR_NOTIMPL;
691 }
692 else
693 {
694 result = server->on_reset(server, msg.content, content_length);
695 }
696 init_msg_base(&msg.base, SOCOP_MSG_RESET_RESPONSE, 0, 0, (socop_word_t)result, msg.base.user_param, 0);
697 result = SOCOP_OK;
698 break;
699 }
700
701 case SOCOP_MSG_NET_STATUS_REQUEST:
702 {
703 if (!server->on_netstatus)
704 {
705 result = SOCOP_ERROR_NOTIMPL;
706 }
707 else
708 {
709 result = server->on_netstatus(server, NULL, 0);
710 }
711 init_msg_base(&msg.base, SOCOP_MSG_NET_STATUS_RESPONSE, 0, 0, (socop_word_t)result, msg.base.user_param, 0);
712 result = SOCOP_OK;
713 break;
714 }
715
716 case SOCOP_MSG_NET_START_REQUEST:
717 {
718 if (!server->on_netstart)
719 {
720 result = SOCOP_ERROR_NOTIMPL;
721 }
722 else
723 {
724 result = server->on_netstart(server, msg.content, content_length);
725 }
726 init_msg_base(&msg.base, SOCOP_MSG_NET_STATUS_RESPONSE, 0, 0, (socop_word_t)result, msg.base.user_param, 0);
727 result = SOCOP_OK;
728 break;
729 }
730 case SOCOP_MSG_NET_STOP_REQUEST:
731 {
732 if (!server->on_netstop)
733 {
734 result = SOCOP_ERROR_NOTIMPL;
735 }
736 else
737 {
738 result = server->on_netstop(server, NULL, 0);
739 }
740 init_msg_base(&msg.base, SOCOP_MSG_NET_STATUS_RESPONSE, 0, 0, (socop_word_t)result, msg.base.user_param, 0);
741 result = SOCOP_OK;
742 break;
743 }
744
745 case SOCOP_MSG_SOCK_CONNECT_REQUEST:
746 {
747 if (!server->on_connect)
748 {
749 result = SOCOP_ERROR_NOTIMPL;
750 }
751 else
752 {
753 deserialize_addr(&addr, (unsigned char const*)&msg.content[0]);
754 result = server->on_connect(server, &addr, &sock);
755 }
756 init_msg_base(&msg.base, SOCOP_MSG_SOCK_CONNECT_RESPONSE, sock, 0, (socop_word_t)result, msg.base.user_param, 0);
757 result = SOCOP_OK;
758 break;
759 }
760
761 case SOCOP_MSG_SOCK_BIND_REQUEST:
762 {
763 if (!server->on_bind)
764 {
765 result = SOCOP_ERROR_NOTIMPL;
766 }
767 else
768 {
769 deserialize_addr(&addr, (unsigned char const*)&msg.content[0]);
770 result = server->on_bind(server, &addr, &sock);
771 }
772 init_msg_base(&msg.base, SOCOP_MSG_SOCK_BIND_RESPONSE, sock, 0, (socop_word_t)result, msg.base.user_param, 0);
773 result = SOCOP_OK;
774 break;
775 }
776
777 case SOCOP_MSG_SOCK_LISTEN_REQUEST:
778 {
779 if (!server->on_bind)
780 {
781 result = SOCOP_ERROR_NOTIMPL;
782 }
783 else
784 {
785 deserialize_addr(&addr, (unsigned char const*)&msg.content[0]);
786 result = server->on_listen(server, &addr, &sock);
787 }
788 init_msg_base(&msg.base, SOCOP_MSG_SOCK_LISTEN_RESPONSE, sock, 0, (socop_word_t)result, msg.base.user_param, 0);
789 result = SOCOP_OK;
790 break;
791 }
792
793 case SOCOP_MSG_SOCK_ACCEPT_REQUEST:
794 {
795 if (!server->on_accept)
796 {
797 result = SOCOP_ERROR_NOTIMPL;
798 }
799 else
800 {
801 result = server->on_accept(server, msg.base.resource_id, &sock);
802 }
803 init_msg_base(&msg.base, SOCOP_MSG_SOCK_ACCEPT_RESPONSE, sock, msg.base.resource_id, (socop_word_t)result, msg.base.user_param, 0);
804 result = SOCOP_OK;
805 break;
806 }
807
808 case SOCOP_MSG_SOCK_CLOSE_REQUEST:
809 {
810 if (!server->on_close)
811 {
812 result = SOCOP_ERROR_NOTIMPL;
813 }
814 else
815 {
816 result = server->on_close(server, msg.base.resource_id, 0);
817 }
818 init_msg_base(&msg.base, SOCOP_MSG_SOCK_CLOSE_RESPONSE, msg.base.resource_id, 0,
819 (socop_word_t)result, msg.base.user_param, 0);
820 result = SOCOP_OK;
821 break;
822 }
823
824 case SOCOP_MSG_SOCK_RECV_REQUEST:
825 {
826 if (!server->on_recv)
827 {
828 result = SOCOP_ERROR_NOTIMPL;
829 }
830 else
831 {
832 content_length = msg.base.resource_param;
833 if (content_length > SOCOP_MAX_CONTENT_LENGTH)
834 {
835 content_length = SOCOP_MAX_CONTENT_LENGTH;
836 }
837 result = server->on_recv(server, msg.base.resource_id, msg.content, content_length, &content_length);
838 if (SOCOP_OK != result)
839 {
840 content_length = 0;
841 }
842 }
843 init_msg_base(&msg.base, SOCOP_MSG_SOCK_RECV_RESPONSE, msg.base.resource_id, 0,
844 (socop_word_t)result, msg.base.user_param, (socop_word_t)content_length);
845 result = SOCOP_OK;
846 break;
847 }
848
849 case SOCOP_MSG_SOCK_RECVFROM_REQUEST:
850 {
851 if (!server->on_recvfrom)
852 {
853 result = SOCOP_ERROR_NOTIMPL;
854 }
855 else
856 {
857 content_length = msg.base.resource_param;
858 if (content_length > SOCOP_MAX_CONTENT_LENGTH)
859 {
860 content_length = SOCOP_MAX_CONTENT_LENGTH;
861 }
862 result = server->on_recvfrom(server, msg.base.resource_id, &msg.content[6], content_length, &content_length, &addr);
863 if (SOCOP_OK != result)
864 {
865 content_length = 0;
866 msg.base.resource_param = 0;
867 }
868 else
869 {
870 msg.base.resource_param = serialize_addr((unsigned char*)&msg.content[0], &addr);
871 }
872 }
873 init_msg_base(&msg.base, SOCOP_MSG_SOCK_RECVFROM_RESPONSE, msg.base.resource_id, msg.base.resource_param,
874 (socop_word_t)result, msg.base.user_param, (socop_word_t)content_length);
875 result = SOCOP_OK;
876 break;
877 }
878 case SOCOP_MSG_SOCK_SEND_REQUEST:
879 {
880 if (!server->on_send)
881 {
882 result = SOCOP_ERROR_NOTIMPL;
883 }
884 else
885 {
886 result = server->on_send(server, msg.base.resource_id, msg.content, content_length, &content_length);
887 if (SOCOP_OK != result)
888 {
889 content_length = 0;
890 }
891 }
892 init_msg_base(&msg.base, SOCOP_MSG_SOCK_SEND_RESPONSE, msg.base.resource_id, (socop_word_t)content_length,
893 (socop_word_t)result, msg.base.user_param, 0);
894 result = SOCOP_OK;
895 break;
896 }
897
898 case SOCOP_MSG_SOCK_SENDTO_REQUEST:
899 {
900 if (!server->on_sendto)
901 {
902 result = SOCOP_ERROR_NOTIMPL;
903 }
904 else
905 {
906 deserialize_addr(&addr, (unsigned char const*)&msg.content[0]);
907 result = server->on_sendto(server, msg.base.resource_id, &msg.content[6], content_length - 6, &content_length, &addr);
908 if (SOCOP_OK != result)
909 {
910 content_length = 0;
911 }
912 }
913 init_msg_base(&msg.base, SOCOP_MSG_SOCK_SENDTO_RESPONSE, msg.base.resource_id, (socop_word_t)content_length,
914 (socop_word_t)result, msg.base.user_param, 0);
915 result = SOCOP_OK;
916 break;
917 }
918
919 case SOCOP_MSG_SOCK_SHUTDOWN_REQUEST:
920 {
921 if (!server->on_shutdown)
922 {
923 result = SOCOP_ERROR_NOTIMPL;
924 }
925 else
926 {
927 result = server->on_shutdown(server, msg.base.resource_id, msg.base.resource_param);
928 }
929 init_msg_base(&msg.base, SOCOP_MSG_SOCK_SHUTDOWN_RESPONSE, msg.base.resource_id, 0,
930 (socop_word_t)result, msg.base.user_param, 0);
931 result = SOCOP_OK;
932 break;
933 }
934
935 case SOCOP_MSG_SOCK_SELECT_REQUEST:
936 {
937 if (!server->on_select)
938 {
939 result = SOCOP_ERROR_NOTIMPL;
940 }
941 else
942 {
943 flags = msg.base.resource_param;
944 result = server->on_select(server, msg.base.resource_id, &flags);
945 }
946 init_msg_base(&msg.base, SOCOP_MSG_SOCK_SELECT_RESPONSE, msg.base.resource_id, (socop_word_t)flags,
947 (socop_word_t)result, msg.base.user_param, 0);
948 result = SOCOP_OK;
949 break;
950 }
951
952 case SOCOP_MSG_SOCK_PEER_REQUEST:
953 case SOCOP_MSG_SOCK_IOCTL_REQUEST:
954 {
955 result = SOCOP_ERROR_WRONGMESSAGE;
956 break;
957 }
958
959 default:
960 {
961 result = SOCOP_ERROR_WRONGMESSAGE;
962 break;
963 }
964 }
965
966 if (SOCOP_OK != result)
967 {
968 init_msg_base(&msg.base, SOCOP_MSG_SOCK_UNKNOWN, msg.base.resource_id, msg.base.resource_param,
969 (socop_word_t)result, msg.base.user_param, 0);
970 }
971
972 return socop_driver_send_msg(&server->driver, &msg.base, msg.content);
973 }
974
975